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

VB.NET Discussion :

Pb sur TableAdapter.Update -> Vous ne pouvez pas ajouter ou modifier un enregistremen


Sujet :

VB.NET

  1. #1
    Futur Membre du Club
    Inscrit en
    Décembre 2007
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 9
    Points : 7
    Points
    7
    Par défaut Pb sur TableAdapter.Update -> Vous ne pouvez pas ajouter ou modifier un enregistremen
    Bonjour à tous et bonne année 2008 !

    Voici mon problème.

    Mon appli développée en VB.NET sous VS2005 se connecte à une base de donnée Access.
    J'accède aux données et les modifie via un DataSet, des BindingSource et des TableAdapter générés automatiquement lors de l'insertion de la base dans le projet.

    Jusque là, pas de problème, j'arrive à créer des enregistrements simples, à les modifier et à les supprimer.

    Or, je souhaite sur une fenêtre de mon application pouvoir créer-modifier-supprimer des enregistrements 'composés' venant de 2 tables différentes.

    J'ai donc créé la fenêtre suivante.

    Chaque tableau pointe sur le BindingSource correspondant à la bonne table.

    Les boutons + permettent d'afficher dans le cadre en haut ou en bas le formulaire d'ajout d'un enregistrement (respectivement pour Parent et Enfant).
    Les boutons EDIT permettent d'afficher dans le cadre en haut ou en bas le formulaire de modification d'un enregistrement (respectivement pour Parent et Enfant).

    Chaque formulaire possède un bouton OK qui valide dans le DataSet les modifications, et un bouton Annuler qui efface le formulaire sans rien faire au niveau des données.

    Les boutons - permettent de supprimer un enregistrement (respectivement pour Parent et Enfant).

    Le bouton Annuler permet de ne pas enregistrer les modifications dans la base de données (on refuse les changement)
    Le bouton Valider permet d'enregistrer les modifications dans la base de données (on accepte les modifications) et de revenir sur la page principale.

    Actuellement, cela fonctionne, mais un cas particulier me fait planter l'appli.
    En effet, mes 2 tables sont liées, et donc, un enregistrement ENFANT ne peut être créé que si l'enregistrement PARENT existe déjà.
    Or, avec l'incrément automatique d'Access (et d'autres SGBD), si l'on a les enregistrements 1-2-3-4 et que l'on supprime le 4, l'incrément auto reprendra alors à 5 (1-2-3-5 si l'on ajoute un nouvel enregistrement).

    ----------------------------------------
    Voici un exemple de mon problème :

    1) Situation initiale :
    PARENT :
    ID-NOM
    1-Youpi
    2-Youpla
    ENFANT :
    ID-NOM-ID_PARENT
    1-Boum-1
    2-Bim-1
    3-Ploum-2
    4-Plim-2

    2) Je supprime l'enregistrement PARENT d'ID=2 --> J'ai une suppression automatique des enregistrements ENFANT d'ID=3 et ID=4 :
    PARENT :
    ID-NOM
    1-Youpi
    ENFANT :
    ID-NOM-ID_PARENT
    1-Boum-1
    2-Bim-1

    3.1) Je ne valide pas mon formulaire (pas d'enregistrement en base de données) --> Si je rajoute un enregistrement PARENT puis un enregistrement ENFANT qui lui est rattaché, j'obtiens la situation correcte suivante :
    PARENT :
    ID-NOM
    1-Youpi
    3-PloumPloum
    ENFANT :
    ID-NOM-ID_PARENT
    1-Boum-1
    2-Bim-1
    5-Pim-3

    3.2.) En revanche, si je valide mon formulaire (enregistrement en base de données) --> Si je rajoute un enregistrement PARENT puis un enregistrement ENFANT qui lui est rattaché, j'obtiens la situation INCORRECTE suivante :
    PARENT :
    ID-NOM
    1-Youpi
    2-PloumPloum
    ENFANT :
    ID-NOM-ID_PARENT
    1-Boum-1
    2-Bim-1
    3-Pim-2

    ==> L'auto incrémentation ne se fait plus correctement.

    Cela ne pose pas de problème pour la table PARENT car lors de l'update, l'ID sera automatiquement modifié.
    Cependant, cela pose un problème pour la table ENFANT car elle référence alors un enregistrement PARENT qui n'existe plus (ID_PARENT=2 au lieu de ID_PARENT=3).
    Lors de l'update, j'obtiens donc le message d'erreur OleDbException suivant : "Vous ne pouvez pas ajouter ou modifier un enregistrement car l'enregistrement associé est requis dans la table 'PARENT'."
    ----------------------------------------

    ----------------------------------------
    Voici le code utilisé (je ne mets pas les paramètres des procédures pour ne pas trop alourdir) :

    Private Sub FRM_Load
    Me.ENFANTTableAdapter.Fill(Me.MYDATASET.ENFANT)
    Me.PARENTTableAdapter.Fill(Me.MYDATASET.PARENT)
    End Sub

    Private Sub BOUTON_PLUS_Click (La procédure pour la table ENFANT est sur le même modèle)
    If Me.MYDATASET.PARENT.Select("NOM='" & Me.TBX_Nom.Text & "'").Length = 0 Then
    'Si l'enregistrement n'existe pas déjà, on le crée
    Me.MYDATASET.PARENT.AddPARENTRow(Me.TBX_Nom.Text, Me.TBX_Desc.Text)
    Else
    'Sinon, on prévient
    MsgBox("Attention", MsgBoxStyle.Exclamation, "Alerte")
    Me.TBX_Nom.Focus()
    EndIf
    End Sub

    Private Sub BOUTON_MOINS_Click (La procédure pour la table ENFANT est sur le même modèle)
    If Me.DataGridView_PARENT.SelectedRows.Count <> 1 Then
    'Si aucune ligne n'est sélectionnée
    MsgBox("Sélectionner une ligne", MsgBoxStyle.Exclamation, "Alerte")
    Else
    If MsgBox("Sûr?", MsgBoxStyle.YesNo + MsgBoxStyle.Exclamation, "Alerte") = MsgBoxResult.Yes Then
    'Définition de l'enregistrement à supprimer
    Dim DataToDel As MYDATASET.PARENTRow = MYDATASET.PARENT.FindByID(Me.DGV_PARENT.SelectedRows.Item(0).Cells(0).Value)
    'Suppression de l'enregistrement dans le dataset
    DataToDel.Delete()
    End If
    End If
    End Sub

    Private Sub BOUTON_EDIT_Click (La procédure pour la table ENFANT est sur le même modèle)
    'Définition de l'enregistrement à modifier
    Dim DataToModif As MYDATASET.PARENTRow = MYDATASET.PARENT.FindByID(Me.DataGridView_PARENT.SelectedRows.Item(0).Cells(0).Value)
    If Me.MYDATASET.PARENT.Select("NOM='" & Me.TBX_Nom.Text & "'").Length = 0 Or _
    DataToModif.NOM = Me.TBX_Nom.Text Then
    'Si l'enregistrement n'existe pas déjà, on le modifie
    DataToModif.NOM = Me.TBX_Nom.Text
    DataToModif.DESCRIPTION = Me.TBX_Desc.Text
    Else
    'Sinon, on prévient
    MsgBox("Attention", MsgBoxStyle.Exclamation, "Alerte")
    Me.TBX_Nom.Focus()
    End If
    End Sub

    Private Sub BOUTON_ANNULER_Click
    'Rejet des changements effectués sur le dataset
    Me.PNG_ETCreatorDataSet.PARENT.RejectChanges()
    Me.PNG_ETCreatorDataSet.ENFANT.RejectChanges()
    'Retour à la fenêtre principale
    Me.Close()
    End Sub

    Private Sub BOUTON_VALIDER_Click
    'Sauvegarde des changements dans la base de données
    Me.PARENTTableAdapter.Update(Me.MYDATASET)
    Me.ENFANTTableAdapter.Update(Me.MYDATASET)
    'Retour à la fenêtre principale
    Me.Close()
    End Sub
    ----------------------------------------


    ==> Auriez-vous des idées pour que mes ID dans mon DataSet s'incrémentent correctement ?

    Merci d'avance !

  2. #2
    Futur Membre du Club
    Inscrit en
    Décembre 2007
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 9
    Points : 7
    Points
    7
    Par défaut Réponse
    Même si ça n'a l'air d'intéresser personne, voici la solution que j'ai trouvée :
    - Visual Studio me génère automatiquement 1 DataSet (DTS), 2 TableAdapter (PARENT_TBA et ENFANT_TBA), 1 BindingSource pointant sur PARENT (PARENT_BSC) et 1 BindingSource pointant sur les ENFANT correspondant au PARENT sélectionné (PARENTENFANT_BSC) lorsque j'insère mes 2 DataGridView (DGV_PARENT et DGV_ENFANT).
    - Afin de pouvoir modifier la totalité des enregistrements ENFANT dans mon environnement de modification, j'insère une nouvelle DataGridView (DGV_E) non visible sur la form, ce qui me crée automatiquement un nouveau BindingSource (ENFANT_BSC).

    ==> Donc, lorsque je sélectionne un PARENT dans le premier DataGridView, il n'est uniquement affiché que les ENFANT correspondant dans le second DataGridView. Les enregistrements, modifications ou suppressions se font alors en cascade, ce qui simplifie grandement le code. Le second DataGridView n'affichant qu'une partie des ENFANT disponible, le troisième DataGridView permet toutefois d'y accéder.

    Et le code qui va avec :
    'Variable permettant d'enregistrer le dernier ID PARENT lors du chargement de la Form puis de le récupérer à la sauvegarde et fermeture de la Form
    Private VAR_LastID As Integer = Nothing
    'Chargement de la Form
    Private Sub FRM_Load
    'Mise à jour des données
    Me.PARENT_TBA.Fill(Me.DTS.PARENT)
    Me.ENFANT_TBA.Fill(Me.DTS.ENFANT)
    'Récupération du dernier ID
    Dim PRows() As MYDATASET.PARENT.PARENTRow
    PRows = Me.DTS.PARENT.Select()
    Me.VAR_LastID = PRows(PRows.Length - 1).ID
    End Sub

    'Ajout d'un PARENT dans le DGV_PARENT
    Private Sub BOUTON_PLUS_Click (La procédure pour la table ENFANT est sur le même modèle)
    If Me.DTS.PARENT.Select("NOM='" & Me.TBX_Nom.Text & "'").Length = 0 Then
    'Si l'enregistrement n'existe pas déjà, on le crée
    Me.DTS.PARENT.AddPARENTRow(Me.TBX_Nom.Text, Me.TBX_Desc.Text)
    Else
    'Sinon, on prévient
    MsgBox("Attention", MsgBoxStyle.Exclamation, "Alerte")
    Me.TBX_Nom.Focus()
    EndIf
    End Sub


    'Suppression d'un PARENT dans le DGV_PARENT
    Private Sub BOUTON_MOINS_Click (La procédure pour la table ENFANT est sur le même modèle)
    If Me.DGV_PARENT.SelectedRows.Count <> 1 Then
    'Si aucune ligne n'est sélectionnée
    MsgBox("Sélectionner une ligne", MsgBoxStyle.Exclamation, "Alerte")
    Else
    If MsgBox("Sûr?", MsgBoxStyle.YesNo + MsgBoxStyle.Exclamation, "Alerte") = MsgBoxResult.Yes Then
    'Définition de l'enregistrement à supprimer
    Dim DataToDel As MYDATASET.PARENTRow = Me.DTS.PARENT.FindByID(Me.DGV_PARENT.SelectedRows.Item(0).Cells(0).Value)
    'Suppression de l'enregistrement dans le dataset
    DataToDel.Delete()
    End If
    End If
    End Sub


    'Edition d'un PARENT du DGV_PARENT
    Private Sub BOUTON_EDIT_Click (La procédure pour la table ENFANT est sur le même modèle)
    'Définition de l'enregistrement à modifier
    Dim DataToModif As MYDATASET.PARENTRow = Me.DTS.PARENT.FindByID(Me.DGV_PARENT.SelectedRows.Item(0).Cells(0).Value)
    If Me.DTS.PARENT.Select("NOM='" & Me.TBX_Nom.Text & "'").Length = 0 Or _
    DataToModif.NOM = Me.TBX_Nom.Text Then
    'Si l'enregistrement n'existe pas déjà, on le modifie
    DataToModif.NOM = Me.TBX_Nom.Text
    DataToModif.DESCRIPTION = Me.TBX_Desc.Text
    Else
    'Sinon, on prévient
    MsgBox("Attention", MsgBoxStyle.Exclamation, "Alerte")
    Me.TBX_Nom.Focus()
    End If
    End Sub


    'Annulation des différentes modifications apportées à PARENT et ENFANT
    Private Sub BOUTON_ANNULER_Click
    'Rejet des changements effectués sur le dataset
    Me.DTS.PARENT.RejectChanges()
    Me.DTS.ENFANT.RejectChanges()
    'Retour à la fenêtre principale
    Me.Close()
    End Sub

    'Enregistrement des modifications apportées à PARENT et ENFANT
    Private Sub BOUTON_VALIDER_Click
    'Définition des variables de test
    Dim VAR_TabID_BS As New Collection 'BS = BeforeSave
    Dim VAR_TabID_AS As New Collection 'AS = AfterSave
    'Tri des enregistrement par ID ... On ne sait jamais !
    Me.DGV_PARENT.Sort(Me.DGV_PARENT.Columns(0), System.ComponentModel.ListSortDirection.Ascending)
    'Enregistrement des ID des PARENT avant la sauvegarde
    For Each DgvRow As DataGridViewRow In Me.DGV_PARENT.Rows
    If DgvRow.Cells(0).Value > Me.VAR_LastID Then VAR_TabID_BS.Add(DgvRow.Cells(0).Value)
    Next
    'Enregistrement des PARENT
    Me.PARENT_TBA.Update(Me.DTS)
    'Récupération des nouveaux ID access dans le DGV_PARENT
    Me.PARENT_TBA.Fill(Me.DTS.PARENT)
    'Enregistrement des ID des PARENT après la sauvegarde
    For Each DgvRow As DataGridViewRow In Me.DGV_PARENT.Rows
    If DgvRow.Cells(0).Value > Me.VAR_LastID Then VAR_TabID_AS.Add(DgvRow.Cells(0))
    Next
    'Modification, le cas échéant, des ENFANT pour un enregistrement correct (traitement sur la totalité des enregistrements ENFANT donc via la DataGridView DGV_E2)
    Dim i As Integer = 0
    For i = VAR_TabID_BS.Count To 1 Step -1
    If VAR_TabID_BS.Item(i) <> VAR_TabID_AS.Item(i) Then
    For Each DGVRow As DataGridViewRow In Me.DGV_E.Rows
    If DGVRow.Cells(2).Value = VAR_TabID_BS.Item(i) Then DGVRow.Cells(2).Value = VAR_TabID_AS.Item(i)
    Next
    End If
    Next
    Try

    'Enregistrement des ENFANT
    Me.ENFANT_TBA.Update(Me.DTS)
    Catch ex As DBConcurrencyException
    'Gestion de l'accès concurrentiel ==> On laisse faire
    'C'est une erreur spécifique due au fait que je modifie un enregistrement enfant avant de l'enregistrer :
    'Ce n'est pas très propre mais je n'ai trouvé que cette solution pour que cela marche fonctionnellement.

    End Try

    'Retour à la fenêtre principale
    Me.Close()
    End Sub

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

Discussions similaires

  1. Vous ne pouvez pas ajouter ou modifier un enregistrement
    Par Samd59 dans le forum Modélisation
    Réponses: 5
    Dernier message: 13/04/2017, 17h01
  2. Réponses: 4
    Dernier message: 17/07/2014, 11h03
  3. [AC-2003] Vous ne pouvez pas ajouter ou modifier un enregistrement
    Par RoZyk dans le forum IHM
    Réponses: 2
    Dernier message: 11/12/2009, 18h11
  4. Réponses: 4
    Dernier message: 23/04/2009, 21h30
  5. Réponses: 8
    Dernier message: 18/09/2008, 16h27

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