none
(Visual Studio 2008) Résolu - Ado.net – DataSet – Modification des données d'une table ACCESS RRS feed

  • Discussion générale

  • Bonjour,

    J'avoue que je manipule ADO.NET par la copie de bout de code, sans parfois bien comprendre la portée des instructions

    Exemple (Pas de logique métier, uniquement pour illustrer mon problème)
    J'ai une Table CLIENT avec deux champs, NUMCLI et CODPOST
    1  06000
    2  68100
    3  68100
    4  75010
    Je lance une SELECT de cette table CLIENT, et fait une boucle pour les lire
    Au client 2, au contrôle du 68100, je lance une procédure qui remplace dans tous les clients le 68100 par le 68200
    La boucle suivante délivre le client 3, qui a toujours 68100 …..

    Je pense que c'est la manipulation des DATASET qui n'est pas bonne
    J'ai trouvé des informations sur GETCHANGE et MERGE, mais pas d'exemple qui puisse me servir

    Voici le code pour les procédures de lecture

                  //

    ' Table tabPrincipale Public cmdPrincipale As OleDbCommand Public dtaPrincipale As OleDbDataAdapter Public dttPrincipale As DataTable Public dtsPrincipale As New DataSet Public dtrPrincipale As DataRow Public cmdbPrincipale As OleDbCommandBuilder ' Table tabPrincipaleWork Public cmdPrincipaleWork As OleDbCommand Public dtaPrincipaleWork As OleDbDataAdapter Public dttPrincipaleWork As DataTable Public dtsPrincipaleWork As New DataSet Public dtrPrincipaleWork As DataRow Public cmdbPrincipaleWork As OleDbCommandBuilder // Public Sub LecTabPrincipale() Try dtsPrincipale.Clear() cmdPrincipale = New OleDbCommand(sqlRequete) dtaPrincipale = New OleDbDataAdapter(cmdPrincipale) cmdPrincipale.Connection() = dbCnx dtaPrincipale.Fill(dtsPrincipale, "tabPrincipale") dttPrincipale = dtsPrincipale.Tables("tabPrincipale") Catch erreur As Exception MsgErreur = "WmodBaseDonne - Sub LecTabPrincipale " & vbCrLf & " Anomalie pendant l'ordre sql" & sqlRequete & vbCrLf & " Erreur : " & erreur.Message wOK = False Anomalie.ShowDialog() Exit Sub End Try End Sub Public Sub LecTabPrincipaleWORK() Try dtsPrincipaleWork.Clear() cmdPrincipaleWork = New OleDbCommand(sqlRequete) dtaPrincipaleWork = New OleDbDataAdapter(cmdPrincipaleWork) cmdPrincipaleWork.Connection() = dbCnx dtaPrincipaleWork.Fill(dtsPrincipaleWork, "tabPrincipale") dttPrincipaleWork = dtsPrincipaleWork.Tables("tabPrincipale") Catch erreur As Exception MsgErreur = "WmodBaseDonne - Sub LecTabPrincipaleWORK " & vbCrLf & " Anomalie pendant l'ordre sql" & sqlRequete & vbCrLf & " Erreur : " & erreur.Message wOK = False Anomalie.ShowDialog() Exit Sub End Try End Sub

    Voici la lecture et la modification

    sqlRequete = "select * from tabPrincipale"
    Call LecTabPrincipale()
    For Me.wCptBoucle = 0 To (dttPrincipale.Rows.Count - 1)
         //
        Call Modif
         //
    Next
    
    Private Sub Modif()
                                 //
                    dtrPrincipaleWork = dtsPrincipaleWork.Tables("tabPrincipale").Rows(0)
                    dttPrincipaleWork.Rows(0).Item("LigGedCom") = Replace(dttPrincipaleWork.Rows(0).Item("LigGedCom"), wFamCherche, wReplace)
                    cmdbPrincipaleWork = New OleDb.OleDbCommandBuilder(dtaPrincipaleWork)
                    dtaPrincipaleWork.Update(dtsPrincipaleWork, "tabPrincipale")
                    dtsPrincipaleWork.Clear()
                    dtaPrincipaleWork.Fill(dtsPrincipaleWork, "tabPrincipale")
                    dttPrincipaleWork = dtsPrincipaleWork.Tables("tabPrincipale")
                           //
    End Sub

    Il faudrait que les modifications faites dans PrincipaleWork se retrouvent dans Principale

    Ou, si j'ai bien compris ADO, que le DATASET de Principale soit mis à jour par les DATASET de PrincipaleWork

    Pouvez-vous m'aider ?

    Merci



    Cordialement Sauveur CONSALVI


    dimanche 28 octobre 2012 08:10

Toutes les réponses

  • Bonjour

    Pour le debout, je vois quelques erreurs dans Modif :

    Dans la fonction Modif vous changez toujours la premiere ligne

    dtrPrincipaleWork = dtsPrincipaleWork.Tables("tabPrincipale").Rows(0)

    Toujours dans Modif je ne vois pas la raison pour avoir

    cmdbPrincipaleWork = New OleDb.OleDbCommandBuilder(dtaPrincipaleWork)

    Ceci est initialisé mais jamais utilisée.

    Aussi je ne vois pas la raison pour faire

    dtsPrincipaleWork.Clear()

    dtaPrincipaleWork.Fill(dtsPrincipaleWork, "tabPrincipale")

    dttPrincipaleWork = dtsPrincipaleWork.Tables("tabPrincipale")

    après la modif de chaque linge. 1 seule fois à la fin suffira. 

    Cordialement,


    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

    lundi 29 octobre 2012 09:52
  • Bonjour,
    Effectivement, je peux optimiser les codes de mise à jour
    Mais cela sera-t-il suffisant pour régler mon problème ?
    C’est-à-dire retrouver lors de la lecture dans la boucle les mises à jour faites dans la procédure ?
    Voici un exemple :

    Private Sub Lecture()
            sqlRequete = "select * from tabPrincipale"
            Call LecTabPrincipale()
            For Me.wCptBoucle = 0 To (dttPrincipale.Rows.Count - 1)
                '   on récupére Les FAMC, Princpale et Analyse
                wRetour = InStr(dttPrincipale.Rows(Me.wCptBoucle).Item("LigGedCom"), "1 FAMC")
                If wRetour = 0 Then Continue For '   Inutile de continuer si pas de FAMC ....
                wClefFamA = "" : wClefFamP = ""
                wArray = Split(dttPrincipale.Rows(Me.wCptBoucle).Item("LigGedCom"), "|")
                For Me.wCpt = 1 To (wArray.Length - 1)       '   Départ de 1, car en 0 c'est la clef
                    wRetour = InStr(wArray(Me.wCpt), "1 FAMC")
                    If wRetour > 0 Then
                        wArrayVerif = Split(wArray(Me.wCpt), "@")
                        wUniqueString = wArrayVerif(1)
                        wUniqueLong = Val(wUniqueString)
                        If wUniqueLong < wUnicite Then
                            wClefFamA = "0 @" & wUniqueString & "@ FAM"   '   Clef de la famille Analyse
                        Else
                            wClefFamP = "0 @" & wUniqueString & "@ FAM"   '   Clef de la famille Principale
                        End If
                    End If
                    If ((wClefFamA <> "") And (wClefFamP <> "")) Then
                        wOK = True
                        Call EpureFAMC(wClefFamA, wClefFamP)
                        If wOK = False Then Exit Sub
                    End If
                Next
            Next
        End Sub
        Private Sub EpureFAMC(ByVal wClefFamA As String, ByVal wClefFamP As String)
            sqlRequete = "select * from tabPrincipale where INDI = '" & wClefFamA & "'"
            Call LecTabPrincipaleWORK()
            If dttPrincipaleWork.Rows.Count > 0 Then
                If wCleSupp <> Nothing Then '    on supprime la FAMC en plus
                    wArrayVerif = Split(dttPrincipaleWork.Rows(0).Item("LigGedCom"), "|")
                    For Me.wCpt = 0 To (wArrayVerif.Length - 1)
                        wRetour = InStr(wArrayVerif(Me.wCpt), wFamSupp)
                        If wRetour > 0 Then
                            wArrayVerif(Me.wCpt) = ""
                            Exit For
                        End If
                    Next
                    dttPrincipaleWork.Rows(0).Item("LigGedCom") = ""
                    For Me.wCpt = 0 To (wArrayVerif.Length - 1)
                        If wArrayVerif(Me.wCpt) <> "" Then
                            dttPrincipaleWork.Rows(0).Item("LigGedCom") += wArrayVerif(Me.wCpt) & "|"
                        End If
                    Next
                End If
                Dim wNewLigGedCom As String = Replace(dttPrincipaleWork.Rows(0).Item("LigGedCom"), wFamCherche, wReplace)
                dtrPrincipaleWork = dtsPrincipaleWork.Tables("tabPrincipale").Rows(0)
                dttPrincipaleWork.Rows(0).Item("LigGedCom") = wNewLigGedCom
                cmdbPrincipaleWork = New OleDb.OleDbCommandBuilder(dtaPrincipaleWork)
                dtaPrincipaleWork.Update(dtsPrincipaleWork, "tabPrincipale")
                dtsPrincipaleWork.Clear()
                dtaPrincipaleWork.Fill(dtsPrincipaleWork, "tabPrincipale")
                dttPrincipaleWork = dtsPrincipaleWork.Tables("tabPrincipale")
            Else
                My.Computer.Audio.Play(RepApli & "/AlarmeMaison.wav", AudioPlayMode.WaitToComplete)
                MsgErreur = wNiveau & vbCrLf & _
                            "Anomalie, Indi principal non retrouvé : " & wClefFamA & vbCrLf & "sqlRequete : " & sqlRequete
                wOK = False
                Anomalie.ShowDialog()
                Exit Sub
            End If
        End Sub

    C'est un exemple que j'ai "bricolé" en vitesse, je ne peux reprendre la totalité du code

    Je suis obligé d'utiliser Principale et PrincipaleWork, car si je fais les modifiations dans le DTS de lecture, j'ai une erreur à l'exécution

    Mais du coup, j'ai deux DTS différent, et je lance plusieurs fois la procédure alors qu'il n'y a pas lieu

    Je ne sais pas si je me suis fait comprendre ...


    Cordialement Sauveur CONSALVI

    lundi 29 octobre 2012 15:51
  • Bonjour

    J'ai mal à comprendre ce que vous voulez faire.

    Si j’ai bien compris, vous voulez modifier dans une procédure une table SQL et avoir les updates dans un autre.  C’est correct ?

    Pourquoi ça ? Si c’est ça, vous devez utiliser des DataSets (on peut les voir comme copie en mémoire d’une BD), et seulement à la fin enregistrer les modifications.

    Pour faire la sélection dans le DataTable, justement  utilisez la DataTable.Select

    http://msdn.microsoft.com/fr-fr/library/system.data.datatable.select.aspx

     Aussi, envoyez vers la deuxième procédure un DataRow comme paramètre, vous avez déjà l’info dans la mémoire. .

    Cordialement


    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

    mardi 30 octobre 2012 13:57
  • Bonjour,

    Merci d'avoir répondu

    Je me doutais que je ne serai pas clair …

    Je recommence mon exemple

    Ne jugez pas la logique, elle est idiote ! Mais elle illustre ce que je veux obtenir

    Dans la table CLIENT, j'ai un champ CODPOST

    Dans la procédure LECTURE je fais une boucle pour lire cette table

    Pour le premier client trouvé qui a CODPOST égal à 68100, je lance la procédure MODIFCODPOST

    Là, je fais une boucle de lecture de la table CLIENT

    Je suis obligé de changer de DATASET

    Je remplace, pour tous les clients dont le code postal est 68100, je remplace 68100 par 68200

    Quand je reviens dans ma boucle de lecture, je trouve encore des clients qui ont 68100 comme code postal !

    Ceci car le DATASET Client est différent du DATASET ClientWork

    Existe-t-il un moyen de mettre à jour ce DATASET Client par le DATASET ClientWork ?

    La continuation de la boucle de lecture ne trouverai plus de 68100, et ne lancerai plus la procédure MODIFCODPOST

    Bien sur que je peux changer la logique de cas très simpliste. Mais j'ai a traiter un problème bien plus complexe, et je ne peux éviter cette situation

       Private Sub Lecture()
            sqlRequete = "select * from Client"
            Call LecTabClient()
            For Me.wCptClient = 0 To (dttClient.Rows.Count - 1)
                If dttClient.Rows(Me.wCptClient).Item("CodPost") = 68100 Then
                    Call ModifCodPost()
                End If
            Next
        End Sub
    
        Private Sub ModifCodPost()
            sqlRequete = "select * from Client"
            Call LecTabClientWork()
            For Me.wCptClientWork = 0 To (dttClientWork.Rows.Count - 1)
                dttClientWORK.Rows(0).Item("CodPost") = 68200
                cmdbClientWORK = New OleDb.OleDbCommandBuilder(dtaClientWORK)
                dtaClientWORK.Update(dtsClientWORK, "tabClient")
            Next
            dtsClientWORK.Clear()
            dtaClientWORK.Fill(dtsClientWORK, "tabClient")
            dttClientWORK = dtsClientWORK.Tables("tabClient")
        End Sub

     


    Cordialement Sauveur CONSALVI

    mardi 30 octobre 2012 14:55
  • Maintenant c'est plus clair. Quand-même je pense que vous devez changer la logique.

    La solution reste dans DataTable.Merge

    http://msdn.microsoft.com/fr-fr/library/system.data.datatable.merge.aspx

    L’ exemple  ici n’est pas clair ?

    Ce que vous interesse est la ligne :

     table1.Merge(table2, false, MissingSchemaAction.Add);

    Dans ce cas veut dire : je veux actualiser l’info de table1 avec l’info de table2, sans modifier table2.
    Pour que ça marche on a besoin d’une clé primaire dans table1 et table2 pour que le Framework sache où il doit ajouter une nouvelle ligne ou modifier une ligne existent (dans votre cas un Id unique du client).

    Cordialement,


    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

    mardi 30 octobre 2012 15:14
  • Merci bien

    Je vais tester, et passerai la question en "résolu" si OK

    Je n'ai pas su utiliser "merge" …

    Je ne peux changer la logique !

    Dans l'exemple que j'ai donné, bien sur ! Mais pas dans le projet réel

    Croyez bien que j'ai murement réfléchi l'analyse

    Le problème est très complexe, et je me retrouve devant ce genre de situation


    Cordialement Sauveur CONSALVI

    mardi 30 octobre 2012 16:12
  • Bonjour,

    Nous changeons le type de votre question à « Discussion générale ». Si vous avez plus de temps pour réexaminer la question et fournir plus d'informations, n'hésitez pas à modifier le type du thread à « Question ». Si le problème est résolu, s’il vous plaît partagez la solution avec nous afin que la réponse puisse être trouvée et utilisée par d'autres membres de la communauté ayant des questions similaires.

    Merci !

    Cordialement,

    Aurel


    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

    mercredi 31 octobre 2012 11:59
  • Bonjour,

    Je ne peux supprimer la ligne

    cmdbAnalyse = New OleDb.OleDbCommandBuilder(dtaAnalyse)

    J'ai une erreur à l'exécution

    Mon problème est résolu avec

    dtsPrincipale.Merge(dtsPrincipaleWork, False, MissingSchemaAction.Add)

    PrincipaleWork est le DATASET qui me permet des actions sur la table en cours de traitement

    Grace au "merge", le DATASET de Principale est mis à jour.

    Principale et PrincipaleWork pointent sur la même table

    Je n'ai plus à enlever les erreurs si l'enregistrement est trouvé, ce qui fiabilise le traitement

    C'est bien ce que je cherchai

    Je passe donc le la question a "résolu"

    Merci de laisser un peu de temps aux personnes pour vérifier la réponse …..


    Cordialement Sauveur CONSALVI

    vendredi 2 novembre 2012 17:36