IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Accès aux données Discussion :

Mise a jour Base Access via DataSet


Sujet :

Accès aux données

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    163
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 163
    Points : 70
    Points
    70
    Par défaut Mise a jour Base Access via DataSet
    Bonjour le Forum,

    Bon je manipule un DatagridView que l'utilisateur remplie en fonction de critères de sélection. Un foi le datagridView remplit, il peut modifier ou pas le contenue du datagridView directement dessus. Si il le modifie, je sais que le DataSet est mis a jour automatiquement car le DataGridView et le DataSet sont liés. Maintenant, je voudrais répercuter les modification dans ma Base Access.

    Pour cela je fais ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
            'J'ouvre la connection avec ma Base Access
            CsV.strconn = "Provider=Microsoft.ACE.OLEDB.12.0;Data source = C:\Documents and Settings\vratouis\Desktop\Time Tracking\Base2.accdb"
            Dim cn As New OleDbConnection(CsV.strconn)
            cn.Open()
     
            adp.Update(ds, "MaTable")
            cn.Close()
    Mais ça ne marche pas.

    Pourtant j'ai suivi le cours de Mr Plasserre qui dit, dans le Chapitre 6-6 Partie B "Remplir un DataGrid avec Base de Données via un DataSet", que pour mettre a jour la base access si on fait une modification dans le DataGrid il faut mettre tout simplement dans le bouton mise a jour juste cette ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ObjetDataAdapter.Update(ObjetDataSet, "NomDataTable")
    Qd je lance mon code j'ai cette erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    OleDbCommand.Prepare method requires all parameters to have an explicitly set type.
    Donc j'en conclue d'après ce message d'erreur qu'il faut redéclarer un objet Commande et de le passer en argument au OleDbAdapter. Mais le problème si je déclare un objet Command il faut que je lui passe en paramètre une requête SQL et ma connexion. Mais je n'ai pas de requête... Donc comment je fais?

    Voici le code avec les déclarations mais incomplètes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
            CsV.strconn = "Provider=Microsoft.ACE.OLEDB.12.0;Data source = C:\Documents and Settings\vratouis\Desktop\Time Tracking\Base2.accdb"
            Dim cn As New OleDbConnection(CsV.strconn)
            ' Dim comm As New OleDbCommand('????????)
     
            adp = New OleDbDataAdapter '(la normalement il doit y avoir comm)
            builder = New OleDbCommandBuilder(adp)
            cn.Open()
            adp.Update(ds, "XL")
            cn.Close()
    Et en compilant j'ai ce message d'erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    The DataAdapter.SelectCommand property needs to be initialized.
    Mais comment l'initialiser?

    Le pire c'est que dans tous les sites internet que j'ai visité, il disent tous il faut juste mettre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MondataAdapter.Update(MonDataSet, "MaDataTable")
    Mais ça ne marche pas.... C'est a n'y rien comprendre.

    J'ai certainement pas du comprendre un truc...

    Donc si quelqu'un pouvait me mettre sur la bonne voie je lui en serai tres reconnaissant.

    Merci d'avance et bonne journée.

    Cordialement,
    Vincent

  2. #2
    Expert confirmé
    Avatar de debug
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    1 034
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 034
    Points : 4 093
    Points
    4 093
    Par défaut
    Il faut lui dire quelle est la requête à exécuter.

    Pour la définir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MondataAdapter.UpdateCommand = "ma requete d'update";
    May the Troll, be with you
    (Que le troll soit avec toi)

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    163
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 163
    Points : 70
    Points
    70
    Par défaut
    Salut debug,

    Merci pour ta réponse et de prendre un peut de temps su r mon sujet.

    Alors j'ai vu effectivement qu'il fallait passer par les Command du DataAdapter.
    Je me suis documenté mais ça ne résout pas mon pb...
    Dans ce cas il faut intégrer au Form des Text box et autre control afin de construire la requête qui sera comme paramètre a la Command du DataAdapter. L'utilisateur remplit ces control et clique sur Update si Update il y a et la ça fonctionne.

    Mais dans mon cas je ne veux aucun textBox, aucun control, juste mon utilisateur, mon DatagridView et un bouton. L'utilisateur modifie le Datagrid directement dessus, ce qui modifie le DataSet en même temps.
    Et dans le bouton il y a le code qui permettra le passage entre le DataSet et la Base de donnée par le biais du DataAdapter.

    Parce que j'ai le soucis d'essayer de rendre les choses le plus simple possible pour les utilisateurs. Et la le fait de modifier directement dans le DataGrid c'est relativement simple d'utilisation.

    Peut être que ce que je ceux faire n'est pas possible? Ou il est probable que je n'ai pas encore bien compris le principe du DataAdapter dans le sens DataSet->Base de donnée.

    Voila je suis toujours en mode recherche et d'épluchage de site internet afin de trouver solution a mon pb... mais sans succès pour le moment...

    Voila si tu as une idée Forum ou toi debug sur la façon de procéder, un cours ou un tuto qui explique comment faire je suis preneur.

    En tout cas Merci pour ton aide

    Bonne journée

    Vincent

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    374
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 374
    Points : 451
    Points
    451
    Par défaut
    Bonjour,
    Pour que l'update fonctionne il faut que les requêtes(update,select, insert, delete) du dataadapter soient crées.
    Le plus facile est d'utiliser l'assistant de création d'une table qui va générer automatiquement ces requêtes.

    Une autre solution, mais qui demande plus de code, est d'utiliser un objet command et de lui passer la requête de mise à jour.
    La procédure consiste à récupérer les lignes modifiées de la table avec un dataview.RowStateFilter.
    Pour chaque type de mise à jour (insert,update,delete) créér le texte de la requête (avec l'utilisation des paramètres pour les champs à traiter).
    Exécuter la requête avec la propriété execnonquery de l'objet command.
    Cette procédure est plus longue mais te permet de mieux gérer la mise à jour.
    D'ailleurs si tes tables ont des relations "clé étrangère", la mise à jour via le dataadapter risque de ne pas fonctionner(intégrité référentielle).
    Bon boulot Jean

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    163
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 163
    Points : 70
    Points
    70
    Par défaut
    Salut JPelli, le Forum

    Alors merci pour tes conseils.... Je suis tombé sur un cours celui de J-M Rabilloud sur ADO.Net, et dans la partie Stratégies de Mise a jour, il explique comment créer les Command du DataAdapter. Je pars donc vers ta deuxièmes méthode (plus fastidieuse certes mais plus sure...)

    Qd tu dis:
    La procédure consiste à récupérer les lignes modifiées de la table avec un dataview.RowStateFilter.
    La table dont tu parles c'est mon dataTable?

    J'ai suivit son cours et j'ai créer trois Fonctions pour chaque type de Mise a jour (Delete-Insert-Update) avec les requêtes paramétrées adéquates. Ca c'est fait et c'était pas trop compliqué...

    Ensuite c'est la ou ça se complique:
    Je me suis renseigné sur le dataview.RowStateFilter. Si j'ai bien compris c'est une sorte de Filtre qui mémorise les modifications faites dans le DataSet et fait le lien entre le dataSet et le DataAdapter. Ensuite, on peut alors utiliser les Command de mise a jour du DataAdapter et mettre a jour la table de données. C'est bien ca?

    Bon si c'est ca dans mon bouton "Mise a jour" dans mon formulaire, il faut que je déclare un objet Commande et un dataView mais comment l'utiliser? Dans l'aide en ligne de VB 2008 Express il mette ça comme exemple pour choper les lignes modifiées:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
            Dim dataView As New DataView(dataTable)
     
            DataView.RowStateFilter = _
    DataViewRowState.Added Or DataViewRowState.ModifiedCurrent
    après je mets les propriété Command au DataSet:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    MonDataSet.UpdateCommand = MaCommande
    MonDataSet.InsertCommand = MaCommande
    MonDataSet.DeleteCommand = MaCommande
    Et la il faut exécuter la requête avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MaCommande.ExecuteNonQuery()
    Le truc c'est que je ne sais pas trop quoi mettre et surtout dans le quel ordre?

    Ensuite comment sait on le type de requête qui a été exécutée?

    J'avoue que je suis complètement perdu...

    Si une âme généreuse pouvait m'aider

    Merci d'avance et bonne journée...

    Vincent

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    374
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 374
    Points : 451
    Points
    451
    Par défaut
    Bonjour,
    Voici un petit exemple
    Dans ce cas j'utilise une procédure stockée pour chaque type de mise à jour
    Procédure de mise à jour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    ......
    dim DTAV as dataview
    DTAV.Table = DS.TGRPCODES      'table parent
    DTAV.RowStateFilter = DataViewRowState.Added Or
          DataViewRowState.Deleted Or DataViewRowState.ModifiedCurrent
            For Each DTARV In DTAV
            Select Case DTARV.Row.RowState
              Case DataRowState.Added
                S_InsertTGRPCODES(SQLCMDGrp, DTARV)
                
    'mise à jour de la table enfant
                DTAR = DTARV.Row
                DTAREnfS = DTAR.GetChildRows("TGRPCODES_TCODMED")
                For Each DTAREnf In DTAREnfS
                  DTAREnf.Item(2) = NumGrp
                  S_InsertTCODMED(SQLCMDCod, DTAREnf)  
              Next
            case DataRowState.Deleted
     ...
            End Select
          Next
          SQLCON.Close()
    procédure ajout
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Private Sub S_InsertTGRPCODES(ByRef SQLCMD As SqlClient.SqlCommand, ByVal DTARV As DataRowView)
           S_CreerParamInsUptTGRPCODES(SQLCMD)   'créer les paramètres
           S_ValueParamInsUptTGRPCODES(SQLCMD, DTARV)   'maj des paramètres
          SQLCMD.CommandText = "ProcInsertTGRPCODES"     'procédure stockées
             sqlcmd.ExecQuery
        End Sub
    procédure création des paramètres
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     Public Sub S_CreerParamInsUptTGRPCODES(ByRef SQLCMD As SqlClient.SqlCommand)
     
          SQLCMD.Parameters.Clear()
        SQLCMD.CommandType = CommandType.StoredProcedure
        With SQLCMD.Parameters
          .Add(New SqlClient.SqlParameter("@Ett", SqlDbType.VarChar, 6))
          .Add(New SqlClient.SqlParameter("@DatHist", SqlDbType.DateTime))
          .Add(New SqlClient.SqlParameter("@NumGrp", SqlDbType.Int))
          .Add(New SqlClient.SqlParameter("@MemoGrp", SqlDbType.VarChar, 10))
          .Add(New SqlClient.SqlParameter("@LibGrp", SqlDbType.VarChar, 50))
          .Add(New SqlClient.SqlParameter("@UtilModif", SqlDbType.VarChar, 20))
        End With
    procédure de mise à jour des paramètres

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Public Sub S_ValueParamInsUptTGRPCODES(ByRef SQLCMD As SqlClient.SqlCommand, ByVal DTARV As DataRowView)
        With SQLCMD
          .Parameters("@Ett").Value = DTARV.Item(0).ToString.Trim
          .Parameters("@DatHist").Value = DTARV.Item(1)
          .Parameters("@NumGrp").Value = CInt(DTARV.Item(2).ToString)
          .Parameters("@MemoGrp").Value = DTARV.Item(3).ToString.Trim
          .Parameters("@LibGrp").Value = DTARV.Item(4).ToString.Trim
          .Parameters("@UtilModif").Value = DTARV.Item(5).ToString.Trim
        End With
    Dans la procédure insert, je mets à jour 2 tables avec une relation donc le dois mettre à jour la table(TGRPCODES) parent et ensuite la table(TCODMED) enfant.
    J'espère que cela t'aideras, n'hésite pas à poser des questions.
    Bon boulot Jean

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    163
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 163
    Points : 70
    Points
    70
    Par défaut
    Salut JPelli, le Forum,

    Merci pour tes explications je commence peut être a sortir de ma grotte et a y voire de la lumière, très fine mais de la lumière qd même....

    Ce pendant j'ai quelque petites questions:

    Le but d'avoir une Datatable Parent et une Datatable Enfant sert a quoi?
    La table parent je pense doit être la table de référence ou d'origine et on filtre les modifications avec le dataview.RowStateFilter. Et pour chaque cas de modification (add-delete-modification) on met a jour la table Enfant. C'est bien ça?

    Si c'est ça donc ma Table Parent doit être ma DataTable qui contient le résultat de ma requête SELECT qui me permet de traiter les données que je souhaite. Et je suppose aussi que la table enfant il faut que je la crée et je dois la remplir avec t'as fonction S_InsertTCODMED(SQLCMDCod, DTAREnf) qui doit avoir le même modèle que S_InsertTGRPCODES(SQLCMDGrp, DTARV)

    Bon jusque la je pense que j'ai compris sauf si....

    Ensuite pb de variable:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    DTARV = DataRowVersion? ie DataTable Version Original Donc DataTable Parent?
    DS = DataSet?
    TGRPCODES = ?
    J'imagine aussi que pour le cas delete et modification, le code est le meme sauf qu'il faut que je créer 3 fonctions pour delete et modification.
    Mais dans tout ça ou je mets les requêtes Insert-Delete-Update ? Çà je ne comprend toujours pas je sais pas. Ça bloque!!!!!!

    Voila j'espère que j'ai bien compris au chmilblique.....

    Encore MERCI de m'aider. Je ne pensais pas que ça serait aussi peu évident...

    Vincent.

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    374
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 374
    Points : 451
    Points
    451
    Par défaut
    Bonjour,
    Au début c'est pas évident et peu à peu on n'y réfléchis même plus.
    Les relations parent-enfant sont utilisées pour garantir l'intégrité référentielle des BDR.
    Dans ton cas tu n'as qu'une table donc cela ne te sert pas.
    On va faire plus simple, sans relation et sans paramètres(si tu maitrises cette façon plus tard tu pourras utiliser les paramètres).
    Ce code met à jour la Base de Données.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    dim DTAV as dataview
    dim DTARV as datarowview
    dim CMD as new objet.command
    dim SCmd as string          'texte de la requête ajout,suppression, modif
    dim DTAV = new dataview
     DTAV.Table = Dataset.NomTable
     CMD.Connection = TaConnection
     CMD.CommandText = SCmd
     CMD.CommandType = CommandType.Text
     DTAV.RowStateFilter = DataViewRowState.Added Or 
                                     DataViewRowState.Deleted Or 
                                     DataViewRowState.ModifiedCurrent
          For Each DTARV In DTAV
            Select Case DTARV.Row.RowState
              Case DataRowState.Added           'ajouter un enregistrement
                With DTARV
                  SCmd = "INSERT INTO NomDeLaTable "
                  SCmd &= String.Format("VALUES({0}, {1}, 
                                {2}, '{3}', '{4}', '{5}') ", _
                              .item(0), .item(1), .item(2),.item(4),.item(5),.item(6))
                  cmd.commandtext = scmd
                  cmd.ExecuteNonQuery
              Case DataRowState.Deleted           'supprimer un enregistrement
                With DTARV
                  SCmd = "DELETE FROM NomDeLaTable "
                  SCmd &= String.Format("WHERE An = {0} and Num = {1} and NumSrv = {2} ", .item(x), .item(y), .item(z))
                  cmd.ExecuteNonQuery
              Case DataRowState.Modified          'modifier un enregistrement
                With DTARV
                  SCmd = "UPDATE NomDeLaTable "
                  SCmd &= String.Format("SET Champ1 = '{0}', Champ2= '{1}', Champ3  = '{2}' ", .item(1),.item(2), .item(3)
                  SCmd &= String.Format("WHERE Cle1 = {0} and cle2 = {1}", .item(0), .item(1)
                  cmd.ExecuteNonQuery
            end select
           next
    String.format facilite la mise en forme surtout pout les "'" mais & fonctionne bien aussi.
    Pour les DTARV.item, ils doivent correspondre à ton enrrgistrement

    Pour le dataset :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dataset.table.AcceptChanges()
    De cette façon les mises à jour de la BDR et du dataset son effectuées.
    If faut aussi ajouter le gestion des erreurs bloc Try, Catch, end try
    Bon courage et si tu as besoin d'aide ....
    Jean

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    163
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 163
    Points : 70
    Points
    70
    Par défaut
    Salut JPelli,

    Alors tout d'abord un grand Merci pour le temps que tu passes sur mon pb.

    J'ai juste une petite question:

    Dans ton SCmd les valeurs que j'attribue :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "VALUES({0}, {1}, {2}, '{3}', '{4}', '{5}')
    Représentent le nom de mes champs... donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "VALUES({Champ0}, {Champ1}, {Champ2}, '{Champ3}', '{Champ4}', '{Champ5}')
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    .item(0), .item(1), .item(2),.item(4),.item(5),.item(6)
    représentent les "nouvelles" valeurs de mon enregistrement c'est ce que tu m'as dit mais je ne les laisse pas comme ca il faut que je change les valeurs?

    Je laisse le code tel qu'il est ou je fais les modification en fonction des nom de mes champs? Je pense que oui.... il faut que je fasse les changement mais alors je mets quoi dans les .item(0)?

    Bon chez moi il est 22h45 donc je vais tester tout ca demain matin.
    Et je te tiendrais au courant.

    En tout cas Merci pour ton aide...

    Bonne fin d'aprem

    Vincent.

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    374
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 374
    Points : 451
    Points
    451
    Par défaut
    Bonjour,
    la table dans ton dataset est déjà mise à jour il faut donc transférer les valeurs modifiées de la table du dataset vers la table de la base de données.
    les nouvelles valeurs se trouvent dans le datarowview.(DTAV) il faut donc récupérer les valeurs des champs de DTAV (se sont les .item) pour mettre à jour la requête.

    SCmd représente le texte requête qui sera envoyée vers la BDR.
    En effet value représente la liste des champs de la table de la bdr à modifier.
    Supposons que ta table possède 2 champs numériques(pour faire simple)
    ta requête sql ressemble à "insert into Table values(125, 358)"
    Dans ton programme
    scmd = string.format("insert into table VALUES("{0}, {1}", dtav.item(0),dtav.item(1))
    Une autre façon (sans string.format)
    scmd = "insert into table VALUES(" & DTAV.item(0) & ", " & dtav.item(1) & ") "
    si dans le debugger tu affiches SCmd tu dois retrouver le texte de la requête sql.

    D'ailleurs pour vérifier la requête, tu exécutes le texte de SCmd dans un éditeur sql .

    Je me rend compte que cette méthode "manuelle" requiert des connaissances en sql alors si tu as des problèmes n'hésite pas à demander.
    A demain Jean

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    163
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 163
    Points : 70
    Points
    70
    Par défaut
    Salut JPelli, le Forum,

    C'est nickel ca marche tres bien sauf l'Update mais c'est normal car il a une couille dans la clause WHERE:

    Voici le code en entier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
            Dim DataV As DataView
            Dim DataRV As DataRowView
            Dim conn As New OleDb.OleDbConnection(CsV.strconn)
            Dim Comm As New OleDbCommand
            Dim SCmd As String
            DataV = New DataView
            DataV.Table = ds.Tables("Time")
            Comm.Connection = conn
            'Comm.CommandText = SCmd
            Comm.CommandType = CommandType.Text
            conn.Open()
            DataV.RowStateFilter = DataViewRowState.Added Or DataViewRowState.Deleted Or DataViewRowState.ModifiedCurrent
            For Each DataRV In DataV
                Select Case DataRV.Row.RowState
                    Case DataRowState.Added
                        With DataRV
                            SCmd = "INSERT INTO Table (Champ1, Champ2, Champ3, Champ4, Champ5, Champ6) "
                            SCmd &= String.Format("VALUES ('{0}', #{1}#, '{2}', '{3}', '{4}', '{5}') ", .Item(0), .Item(1), .Item(2), .Item(3), .Item(4), .Item(5))
                            Comm.CommandText = SCmd
                            Comm.ExecuteNonQuery()
                        End With
                    Case DataRowState.Deleted
                        With DataRV
                            SCmd = "DELETE FROM Table "
                            SCmd &= String.Format("WHERE Champ1 = '{0}' And Champ2 = #{1}# And Champ3 = '{2}' And Champ4 = '{3}' And Champ5 = '{4}' And Champ6 = '{5}' ", .Item(0), .Item(1), .Item(2), .Item(3), .Item(4), .Item(5))
                            Comm.CommandText = SCmd
                            Comm.ExecuteNonQuery()
                        End With
                    Case DataRowState.Modified
                        With DataRV
                            SCmd = "UPDATE Table "
                            SCmd &= String.Format("SET Champ1 = '{0}', Champ2 = #{1}#, Champ3 = '{2}', Champ4 = '{3}', Champ5 = '{4}', Champ6 = '{5}' ", .Item(0), .Item(1), .Item(2), .Item(3), .Item(4), .Item(5))
                            SCmd &= String.Format("WHERE Champ1 = '{0}' And Champ2 = #{1}# And Champ3 = '{2}' And Champ4 = '{3}' And Champ5 = '{4}' And Champ6 = '{5}' ", .Item(0), .Item(1), .Item(2), .Item(3), .Item(4), .Item(5))
                            Comm.CommandText = SCmd
                            Comm.ExecuteNonQuery()
                        End With
                End Select
            Next
            ds.Tables("Time").AcceptChanges()
            conn.Close()
    En fait qd je regarde dans le Debug, la clause Where est identique a la Clause Set ce qui ne doit pas être le cas... Donc il prend bien les modifications dans le Set et les critères dans Where sont aussi les modifications donc il cherche ce qui n'existe pas encore...

    As tu une idée?

    En tout cas un grand MERCI pour tout

    Bonne journée,

    Vincent

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    374
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 374
    Points : 451
    Points
    451
    Par défaut
    Bonjour,
    La clause SET contient les champs à modifier
    La clause Where contient les champs de sélection des enregistrements, en géneral il s'agit de la clé de l'enregistrement.
    si tu as une table de 5 champs avec la clé Champ1 et champ2
    la requête ressemble à

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SCmd = "UPDATE Table "
    SCmd &= String.Format("SET Champ3 = '{2}', Champ4 = '{3}', Champ5 = '{4}', Champ6 = '{5}' ", .Item(2), .Item(3), .Item(4), .Item(5))
    SCmd &= String.Format("WHERE Champ1 = '{0}' And Champ2 = #{1}# ", .Item(0), .Item(1))
    Comm.CommandText = SCmd
    Comm.ExecuteNonQuery()
    en clair et sql

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     UPDATE Table SET champ3 = 'xxx', Champ4 = 'yyyyyy', champ5 = 'zzz', champ6 = 'aaaa'
    where Champ1 = 11 and champ2 = 22222
    Il n'est pas possible de modifier un champ clé, il faut supprimer et ajouter un enregistrement.
    J'espère que cela t'aideras.
    Bon boulot Jean

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    163
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 163
    Points : 70
    Points
    70
    Par défaut
    Salut JPelli, le Forum,

    Bah en fait dans ma table je n'ai pas de Primary Key. Ca peut paraitre bizar mais les infos qui y sont rentrées peuvent toutes être identiques.

    Enfait je fait du Time Tracking sur des projets. Et chaque Membre d'un projet remplit dans une table Time le temps passé sur un ou plusieur projet. Le truc c'est que dans cette Table y a tout le monde qui y remplit des données. Ma Table possède 6 Champs (Login, WorkDay, Heur de début, Heur de Fin, NomProjet et Département). Et dans un meme jour, Une personne peut travailler sur le projetA du DepartementA et sur le ProjetB du DepatementA. Donc il va remplire par exemple 9h-13h et 14h-20h par exemple et un autre gars va bosser sur idem sur ces deux projets et il va mettre 8h30-14h et 15h-19h. Dans a la fin de la journée dans ma Table il y aura ca:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Login   WorkDay   HeurDeb   HeurFin   Proj   Depart
     Titi    21/5/2008     9h           13h     PA     DepA
     Titi    21/5/2008     14h         20h      PB     DepA
     Toto  21/5/2008    8h30        14h      PB     DepA
     Toto  21/5/2008    15h          19h     PA     DepA

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    163
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 163
    Points : 70
    Points
    70
    Par défaut
    Oups mauvais bouton.....

    Donc voila dans ma Table il ne peut y avoir de Clef Primaire.

    Et ensuite, le Chef de Proj doit approuver ou non ces données. Par exemple si titi dit qu'il a bossé 5h sur un projet dans une aprem et que le Chef de Proj l'a vu se balader ou je sais pas faire autre chose que bosser bah il va modifier les valeurs.
    Ce qui est l'objet de cette discussion.

    Maintenant tu vois un peut mieux comment c'est fait...

    Donc revenons a nos moutons:
    Si je ne met pas de clause WHERE c'est pas bon.
    Si je met mon Champ login en temps que clef c'est pas bon du tout car ca va me changer toute les lignes qui ont se login. Et Idem pour les autres champs.
    Parce que en fait le Chef de Projet va en grande majorité modifié le volume horaire donc HeurDeb et HeurFin.

    Peut être que je peut mettre dans ma table un champs num auto qui sera ma clef mais je ne veut pas qu'elle soit affichée dans mon DataGridView mais je ne sais pas trop comment forcer mon DataGridView a afficher uniquement les Champs 2 a 7. Ca peut etre une idée mais je trouve ça crade: magouille et compagnie je suis pas trop fan.....

    Donc voila je vais partir la dessus en tout cas ca va marcher. Reste plus qu'a trouver comment ne pas afficher la première colonne de mon DataTable.

    Si tu as une idée moins crade que la mienne je suis preneur.....

    En tout cas Merci pour tout

    Je testerai tout ça demain...

    Bonne fin d'aprem et a demain

    Vincent.

  15. #15
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    374
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 374
    Points : 451
    Points
    451
    Par défaut
    Bonjour,
    Pour personnaliser les colonnes du datagridview :
    Voici un exemple avec des colonnes textebox et checkbox

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    Dim Col As DataGridViewCheckBoxColumn   'pour créer une colonne Case à cocher
    'empêcher la création automatique des colonnes dans le DGV
        DGV.AutoGenerateColumns = False
        With DGV.Columns
     'pour être sur qu'il n'y a plus de colonnes
          .Clear()   
    'créer une colonne de type textbox        
          .Add("LibSerie", "Série")
    'lier la colonne à la colonne de la table
          .Item("LibSerie").DataPropertyName = "LibSerie"   
    'déterminer la largeur de la colonne
          .Item("LibSerie").Width = 80
    'nouvelle colonne
          .Add("NomEditeur", "Editeur")
          .Item("NomEditeur").Width = 100
          .Item("NomEditeur").DataPropertyName = "NomEditeur"
          .Add("NumAlbum", "Num")
         .Item("NumAlbum").DataPropertyName = "NumAlbum"
          .Item("NumAlbum").Width = 30
          .Add("Titalbum", "Titre album")
          .Item("TitAlbum").Width = 150
          .Item("TitAlbum").DataPropertyName = "TitAlbum"
    'création de la colonne CheckBox(ca marche si la colonne de la table est de type Boolean ou si la colonne contient des valeurs 0,1
    'c'ets une autre façon de créer des colonnes avec un objet dataviewcolumns
          Col = New DataGridViewCheckBoxColumn
    'le nom de la colonne
          Col.Name = "Dedicace"
    'lier la colonne à la colonne de la table
          Col.DataPropertyName = "Dedicace"
    'l'entête de colonne dans le DGV
          Col.HeaderText = "Dédicacé"
    'la largeur de la colonne
          Col.Width = 50
    'ajouter la colonne au dgv
          .Add(Col)
        End With
    dans l'"exemple précédent j'aurai pu créer les colonnes textbox avec un objet DataGridViewTextBoxColumn, le résultat est le même
    exemple pour la première colonne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    Dim ColTB As DataGridViewTextBoxColumn
     ColTB = New DataGridViewtextBoxColumn
    'le nom de la colonne dans le DGV
          ColTB.Name = "LibSerie"
    'lier la colonne du DGV à la colonne de la table
          ColTB.DataPropertyName = "LibSerie"
    'l'entête de colonne dans le DGV
          ColTB.HeaderText = "Série"
    'la largeur de la colonne
          ColTB.Width = 80
    'ajouter la colonne au dgv
          .Add(Col)
    'Pour une nouvelle colonne recommencer la procédure, tu peux réutiliser le même datagridviewtextboxcolumn
     ColTB = New DataGridViewtextBoxColumn
    'le nom de la colonne dans le DGV
          ColTB.Name = "NomEditeur"
    .....
    Bon courage. Jean

  16. #16
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    163
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 163
    Points : 70
    Points
    70
    Par défaut
    Salut JPelli, le Forum,

    Bon je suis parti comme je te l'ai dit hier sur une autre colonne dans ma table mais le pb c'est que je veux qu'elle soit complètement transparente pour les utilisateurs. Je ne veux pas qu'il ait a remplir un champs de type numérique afin d'avoir une clef primaire. Mais le pb c'est que je ne sais pas trop comment générer automatiquement cette clef lors de la création d'une nouvelle ligne et idem qd je supprime une ligne, Access ne met pas a jour les numéro de ligne donc si par exemple il y a 4 lignes dans ma base et que je supprime la ligne 2 par ex je vais avoir L1, L3, L4. Et ca peut poser problème lors du traitement.

    Y aurait il la possibilité de récupérer les anciennes valeurs du dataTable avant modification du style:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     Case DataRowState.Modified
                        With DataRV
                            SCmd = "UPDATE Table "
                            SCmd &= String.Format("SET Champ1 = '{0}', Champ2 = #{1}#, Champ3 = '{2}', Champ4 = '{3}', Champ5 = '{4}', Champ6 = '{5}' ", .Item(0), .Item(1), .Item(2), .Item(3), .Item(4), .Item(5))
                            SCmd &= String.Format("WHERE Champ1 = Ancienne valeur And Champ2 = Ancienne valeur And Champ3 = Ancienne valeur And Champ4 = Ancienne valeur And Champ5 = Ancienne valeur And Champ6 = Ancienne valeur ", .Item(0), .Item(1), .Item(2), .Item(3), .Item(4), .Item(5))
                            Comm.CommandText = SCmd
                            Comm.ExecuteNonQuery()
                        End With
    Comme ça j'ai ma clause Where pour ma requête Update dans ma table Access.
    Ça serait en fait plus simple pour moi. Sauf si c'est pas possible. Dans ce cas il va falloir que je pense a une autre idée....

    Si tu as une idée comme d'ab je suis preneur...

    Je continue a chercher et te tiendrai au courant...

    Merci et a demain.

    Vincent

  17. #17
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    374
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 374
    Points : 451
    Points
    451
    Par défaut
    Bonjour,
    La table dans le dataset doit reprendre la colonne clé, au niveau du DGV tu peux cacher cette colonne.
    Lors d'un insert la valeur de la clé est générée automatiquement par le système

    Dans le cas de l'update, la clé de l'enregistrement se trouve donc dans le dataRV souvent l'item(0)(on place généralement la clé en première colonne).
    Bon boulot Jean

  18. #18
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    374
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 374
    Points : 451
    Points
    451
    Par défaut
    Autre solution
    Dans la BDR table : T1, Col1(numérique), col2(caractère),col3(caractère) Col1=clé primaire de la table
    Dans le Dataset : TDS1,Col1(numérique), col2(caractère),col3(caractère) Donc les 2 tables sont identique et avec une clé primaire.
    Il faut donc générer la clé manuellement, comme c'est une clé numérique la fonction MAX retourne la plus grande valeur d'une colonne.
    Pour créér la cle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    dim CMD as  New OleDbCommand
    dim SCmd as string
    dim Cle as integer
    scmd = "select isnull(max(Col1),0) from T1 "
    CMD.CommandType = CommandType.commandtext
    CMD.CommandText = scmd
    Cle = CMD.ExecuteScalar
    cle += 1
    ...
    'requête insert avec cle comme valeur de clé primaire.
    Cette solution présente malheureusement quelques problèmes si la BDr est modifiée par plusieurs utilisateurs, en effet la clé générée par l' utilisateur 1 peut aussi être générée par l'utilisateur 2.
    Il est préférable de générer la clé le plus tard possible.
    Lors de l'insert, il faut prévoir une procédure de génération d'une nouvelle clé si la commande d'insertion provoque l'erreur DUPKEY.


    La solution avec clé auto évite cette erreur mais la récupération de la nouvelle clé n'est pas évidente.
    J'éspère que tout cela ne t'embrouille pas trop mais garde courage.
    Jean

  19. #19
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    163
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 163
    Points : 70
    Points
    70
    Par défaut
    Salut JPelli, le Forum,

    Encore Merci pour tout se que tu fais...
    T'inquiète je garde espoir même si je suis un peut perdu mais faut que ça décante...

    Il est vrais que plusieurs utilisateur peuvent faire des modifications en même temps mais pas sur les même ligne car dans mon cas un chef de projet a une équipe et un code projet donc si il veut modifier le temps il peut le faire mais personne d'autre ne pourra modifier ces lignes car se sont ces gars et son projet. même si un ou plusieurs de ses gars sont sur un autre projet ca ne change rien car ils sont affiliés a un autre chef de projet et a un autre code projet... Donc ce devrait pas poser trop de pb.

    Je vais donc partir sur la génération de la clef manuellement...

    Si ca pose pb je reviendrais sur ta première solution.

    Je regarde ca ce We et te tiendrai au courant...

    Encore Merci pour tout bon après midi et surtout bon We

    Vincent.

  20. #20
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    163
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 163
    Points : 70
    Points
    70
    Par défaut
    Salut JPelli, le Forum,

    Ça y est c'est enfin résolut.....

    Voici le code qui permet de faire des modifications (Insert-Update-Delete) dans une Table Access par le biais de modifications directes sur un DataGridView:

    Attention ce code est optimisée pour une table Access ou il faut générer manuellement une clef primaire dans mon cas ma clef primaire c'est "Cle"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
     
        Dim DataV As DataView
        Dim DataRV As DataRowView
        Dim conn As New OleDb.OleDbConnection(CsV.strconn)
        Dim Comm As New OleDbCommand
        Dim SCmd As String
        Dim CMD As New OleDbCommand
        Dim Scmd1 As String
     
            DataV = New DataView
            DataV.Table = ds.Tables("DataTable")
            Comm.Connection = conn
            Comm.CommandType = CommandType.Text
            conn.Open()
            DataV.RowStateFilter = DataViewRowState.Added Or DataViewRowState.Deleted Or DataViewRowState.ModifiedCurrent
            For Each DataRV In DataV
                Select Case DataRV.Row.RowState
                    Case DataRowState.Added
                        With DataRV
     
                            Scmd1 = "SELECT MAX(Champ1) FROM TableAccess"
                            CMD.Connection = conn
                            CMD.CommandType = CommandType.Text
                            CMD.CommandText = Scmd1
                            Cle = CMD.ExecuteScalar
                            Cle += 1
     
                            SCmd = "INSERT INTO TableAccess (Champ1, Champ2, ..., Champn) "
                            SCmd &= String.Format("VALUES ({0}, '{1}', ..., '{n}') ", .Item(0), .Item(1), ..., .Item(n))
                            Comm.CommandText = SCmd
                            Comm.ExecuteNonQuery()
     
                        End With
                    Case DataRowState.Deleted
                        With DataRV
                            SCmd = "DELETE FROM TableAccess "
                            SCmd &= String.Format("WHERE Champ1 = {0} And Champ2 = '{1}' And ... And Champn = '{n}' ", .Item(0), .Item(1), ..., .Item(n))
                            Comm.CommandText = SCmd
                            Comm.ExecuteNonQuery()
     
                        End With
                    Case DataRowState.Modified
                        With DataRV
                            SCmd = "UPDATE TableAccess "
                            SCmd &= String.Format("SET Champ1 = '{0}', Champ2 = '{1}', ..., Champn = '{n}' ", .Item(0), .Item(1), ..., .Item(n))
                            SCmd &= String.Format("WHERE ID = {0} ", .Item(0))
                            Comm.CommandText = SCmd
                            Comm.ExecuteNonQuery()
     
                        End With
                End Select
            Next
            ds.Tables("DataTable").AcceptChanges()
     
            'Vide le DataSet et le remet a jour...
            ds.Clear()
            adp.Fill(ds, "DataTable")
            Me.DataGridView1.DataSource = ds.Tables("DataTable").DefaultView
     
            conn.Close()
    Si vous avez déjà une clé primaire contenu dans votre base regarder quelques postes plus haut et la réponse y est....

    Je tiens a dire un GRAND MERCI a JPelli pour toute l'aide et le temps qu'il a passé sur mon pb... Car sans lui.....

    Bonne journée JPelli,

    Vincent

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [AC-2007] Mise a jour base Access
    Par Aladin_23 dans le forum VBA Access
    Réponses: 6
    Dernier message: 12/05/2010, 21h25
  2. mise a jour base de donnée access
    Par Razielone dans le forum C#
    Réponses: 5
    Dernier message: 28/03/2008, 08h43
  3. [mise a jour] base de donnée access
    Par escobar dans le forum Access
    Réponses: 11
    Dernier message: 17/07/2006, 10h12
  4. Module de Mise à jour BDD access via un site sécurisé
    Par Askarod dans le forum Bases de données
    Réponses: 3
    Dernier message: 08/12/2005, 08h31
  5. Mise à jour base access->mysql impossible... :-(
    Par pako69 dans le forum Administration
    Réponses: 4
    Dernier message: 26/09/2005, 14h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo