Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

Sujet : Pb sur TableAdapter.Update -> Vous ne pouvez pas ajouter ou modifier un enregistrement car l'enregistrement associé est requis dans la table [ Base de données / Access ] (v.massip)

mercredi 9 janvier 2008 à 16:35:52 | Pb sur TableAdapter.Update -> Vous ne pouvez pas ajouter ou modifier un enregistrement car l'enregistrement associé est requis dans la table

v.massip

Membre Club

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 dasn mon DataSet s'incrémentent correctement ?

Merci d'avance !


mercredi 9 janvier 2008 à 16:43:51 | Re : Pb sur TableAdapter.Update -> Vous ne pouvez pas ajouter ou modifier un enregistrement car l'enregistrement associé est requis dans la table

v.massip

Membre Club

Petit raté sur l'image, elle se trouve ici.


vendredi 25 janvier 2008 à 11:16:03 | Re : Pb sur TableAdapter.Update -> Vous ne pouvez pas ajouter ou modifier un enregistrement car l'enregistrement associé est requis dans la table

v.massip

Membre Club
Réponse acceptée !

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 AsInteger = 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)
IfMe.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)
IfMe.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)
IfMe.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 AsNew Collection 'BS = BeforeSave
Dim VAR_TabID_AS AsNew 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
ForEach DgvRow As DataGridViewRow InMe.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
ForEach DgvRow As DataGridViewRow InMe.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 AsInteger = 0
For i = VAR_TabID_BS.Count To 1 Step -1
If VAR_TabID_BS.Item(i) <> VAR_TabID_AS.Item(i) Then
ForEach DGVRow As DataGridViewRow InMe.DGV_E.Rows
If DGVRow.Cells(2).Value = VAR_TabID_BS.Item(i) Then DGVRow.Cells(2).Value = VAR_TabID_AS.Item(i)
Next
EndIf
Next
Try
'Enregistrement des ENFANT
Me.ENFANT_TBA.Update(Me.DTS)
CatchexAsDBConcurrencyException
'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.
EndTry
'Retour à la fenêtre principale
Me.Close()
End Sub




Cette discussion est classé dans : enregistrement, mydataset, id, enfant, parent


Répondre à ce message

Sujets en rapport avec ce message

suppression d'enregistrement parent enfant à partir d'un MSHFLEXGRID [ par alcyr ] Bonjour à tous , je travaille  sur un projet qui necessite  une MSHFLEXGRID. celle ci a pour recordsource un dataenvironment (composé d'une requete sq [VB2005] DragDrop dans un même Treeview [ par Clad49 ] Bonjour !J'ai un treeview comme ci-dessous:Par récupérer l'ID du dernier enregistrement [ par warzog ] Voilà, j'ai une base ACCESS sur laquelle j'ajoute des enregistrements (avec une clé primaire de type NuméroAuto).Ce que j'aimerais, c'est connaître à TREEVIEW - NODES [ par wouailnot ] est- il possible d'afficher dans un treeview au niveau d'un noeud parent le nombre de ses noeuds enfants,tel que :x 1er PARENT (3)....... o 1er Enfant Treeview: comment savoir si on est sur un noeud enfant ou parent? [ par FASH ] Bonjour à tous Comment savoir si on est en présence d'un noeud enfant ou parent lorsqu'on sélectionne un noeud dans un treeview en VB6. Quelles propr Accéder au parent d'un MDI [ par oddler ] Salut, assez simple question ici.J'ai un MDI parent et un enfant, je créer ma connection dans le MDI parent qui ne fait que cela, les autres petits pr Fermer formulaire parent et conserver formulaire enfant [ par Razaphi ] Salut à tous les codeurs. J'ai un petit probleme, le voici. J'ai deux formulaires A et B. Je voudrai executer A et à partir de A lancer le formulaire Récupérer l'ID du dernier enregistrement [ par PatWolver ] Bonjour,Pourriez-vous me dire comment dans une table SQL récupérer l'ID de l'enregistrement qui vient de se faire. Ceci sans relancer une requête pour Parent - Enfant (recuperation de methode) [ par zncpo ] salut, j'ai un frmParent à qui j'ai rajouté 2,3 methodes et j'aimerai pouvoir me servir de ces methodes quand je code les enfants. ex: this.parentfo Une arborescence de dossier dans Access [ par budhax ] Je souhaite modéliser dans MS Access une arborescence de dossier selon le principe suivant:1 - il suffit de connaître le dossier parent de chaque doss


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

Logiciels à télécharger sur le même thème :

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,421 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.