Enregistrer un enregistrement dans deux tables

DAVIMIKA Messages postés 118 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 10 janvier 2014 - 9 janv. 2010 à 09:52
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 - 11 janv. 2010 à 15:23
Bonjour,

Lorsque je crée un enregistrement dans la table Formation-Activité-Liste je voudrais rajouter
l'Id (réfFormationActivitéListe ) ainsi crée dans la table Formation, et lorsqu'il exixte reporter l'id dans la table formations

- Les deux tables sont vide le 1er enregistrement se crée bien dans les deux tables.
- Je choisi un 2ème animateurs pas de problème
- Le 3ème j'ai une bouche sans fin.

Ou se trouve mon erreur ?

Je joins le code, et merci pour votre aide.

Nota : je pourrais mettre en P.J. une base allégée.

Salutations

Private Sub Commande11_Click()
On Error GoTo GestionErreur

Set db = CurrentDb()

'--- Intérogation de rsFormaListe
Set rsFormaListe = db.OpenRecordset("tbl Formations-Activités-Liste", dbOpenDynaset)

'--- Intérogation de rsFormation
Set rsFormation = db.OpenRecordset("tbl Formations", dbOpenDynaset)

'--- Test sur base vide
If rsFormaListe.RecordCount = 0 Then
rsFormaListe.AddNew
rsFormaListe("réfActivitéListe") = Me.txtRéfActivitéListe
rsFormaListe("réfActivitéOption") = Val(Me.cmbOption)
rsFormaListe("réfFormationListe") = Val(Me.cmbFormation)
lngCodeRéf = rsFormaListe("RéfFormationActivitéListe")

rsFormation.AddNew
rsFormation("réfAnimateur") = Nz(TxtRéfAnimateur.Value, 0)
rsFormation("DatesDu") = Nz(txtDateDu.Value)
rsFormation("DatesAu") = Nz(txtDateAu.Value)
rsFormation("réfFormationActivitéListe") = lngCodeRéf
rsFormation.Update
rsFormaListe.Update
End If

'--- Boucle sur la table rsFormaliste
Do While Not rsFormaListe.EOF

'--- Recherche si l'enregistrement est trouvé
rsFormaListe.FindFirst "[RéfActivitéListe]=" & Val(Me.txtRéfActivitéListe) & " And " & _
"[RéfActivitéOption]=" & Val(Me.cmbOption) & " And " & _
"[RéfFormationListe]=" & Val(Me.cmbFormation)

'--- Test sur NoMatch
If rsFormaListe.NoMatch Then
rsFormaListe.AddNew
rsFormaListe("réfActivitéListe") = Me.txtRéfActivitéListe
rsFormaListe("réfActivitéOption") = Val(Me.cmbOption)
rsFormaListe("réfFormationListe") = Val(Me.cmbFormation)
lngCodeRéf = rsFormaListe("RéfFormationActivitéListe")
Else

'--- Trouvé NoMatch on met à jours
rsFormaListe.Edit
End If
rsFormaListe("réfActivitéListe") = Me.txtRéfActivitéListe
rsFormaListe("réfActivitéOption") = Val(Me.cmbOption)
rsFormaListe("réfFormationListe") = Val(Me.cmbFormation)
lngCodeRéf = rsFormaListe("RéfFormationActivitéListe")
rsFormaListe.Update

'--- Maj et Ajout dans la tbl rsFormation

'--- Recherche si l'enregistrement est trouvé
rsFormation.FindFirst "[RéfFormationActivitéListe]=" & rsFormaListe![RéfFormationActivitéListe]

? rsFormation.FindFirst "[RéfFormationActivitéListe]=" & lngCodeRéf

'--- Non trouvé NoMatch on ajoute
If rsFormation.NoMatch Then
rsFormation.AddNew
rsFormation("réfAnimateur") = Nz(TxtRéfAnimateur.Value, 0)
rsFormation("réfFormationActivitéListe") = lngCodeRéf
Else

'--- Trouvé NoMatch vau on met à jours
rsFormation.Edit
End If
rsFormation("réfAnimateur") = Nz(TxtRéfAnimateur.Value, 0)
rsFormation("DatesDu") = Nz(txtDateDu.Value)
rsFormation("DatesAu") = Nz(txtDateAu.Value)
rsFormation.Update
rsFormaListe.MoveNext
Loop

'--- Màj du sous formulaire
Forms![frm Màj Formations]![frm Màj Formations-sfm].Requery

'--- Ferme les objet
rsFormaListe.Close: Set rsFormaListe = Nothing
rsFormation.Close: Set rsFormation = Nothing
db.Close: Set db = Nothing

GestionErreur:

End Sub

19 réponses

cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
9 janv. 2010 à 10:49
Salut
Ma boule de cristal me dit que tu es sous Access.
Merci d'utiliser la coloration syntaxique la prochaine fois (3ème icone à partir de la droite) = plus facile à lire (et moins chiant pour rechercher les End If ou autre Loop)

En lisant ton code, je vois :[list]
[*] que tu orthographies les noms des champs différemment d'une ligne à l'autre : tantôt avec majuscule, tantôt sans : méfie-toi !
[*] que tu insères des chiffres puisque tu utilises Val, mais pas tout le temps
[*] après le "'--- Trouvé NoMatch on met à jours", tu fais soit un AddNew, soit un Edit. Ok
Mais le renseignement des valeurs de chaque champ est commun aux deux : Donc, inutile de le répéter deux fois :
'--- Test sur NoMatch 
If rsFormaListe.NoMatch Then 
  '--- Pas trouvé : ajout  
  rsFormaListe.AddNew 
Else 
  '--- Trouvé NoMatch on met à jours 
  rsFormaListe.Edit 
End If 
'--- Renseigne fiche insérée ou trouvée
rsFormaListe("réfActivitéListe") = Me.txtRéfActivitéListe 
rsFormaListe("réfActivitéOption") = Val(Me.cmbOption) 
rsFormaListe("réfFormationListe") = Val(Me.cmbFormation) 
lngCodeRéf = rsFormaListe("RéfFormationActivitéListe") 
rsFormaListe.Update

[*] Problème dans ta boucle Do-Loop
Tu fais une boucle sur le RecordSet rsFormaListe, mais dans ta boucle, tu fais un FindFirst --> La boucle perd sa position et, en effet, si la fiche existe déjà, tu tourne en rond.
Si tu dois faire une recherche sur un RecordSet et que tu ne veux pas perdre l'emplacement où tu te trouves, il faut dupliquer le RecordSet avec la fonction .Clone et faire le FindFirst sur le clone.
Ce clonage n'est pas une copie, juste une astuce de gestion de bookmark, donc elle ne gaspille pas de mémoire.
Inspire toi de <ces explications> car il me semble qu'on ne peut pas faire de recherche multi critères (plusieurs champs) avec un FindFirst/list
Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
0
DAVIMIKA Messages postés 118 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 10 janvier 2014
9 janv. 2010 à 11:11
Bonjour Jack,

Merci pour tes explications dont je vais m'inspirer aussitôt.

Je ne trouve pas la fonction pour modifier mon message et mettre la coloration syntaxique.

Par contre
ta boule de cristal me dit
fonctionne très bien puisque je suis sous Access 2003.

A+

Salutations
0
DAVIMIKA Messages postés 118 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 10 janvier 2014
9 janv. 2010 à 12:38
Re bonjour,

Peux-tu me donner un exemple d'un FindFiste sur un clone, j'ai essayé, mais comme je n'ai jamais fait cela
je n'y arrive pas.

Salutations
0
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
9 janv. 2010 à 13:10
Regarde dans le lien que je t'ai fourni.
Sinon, sans passer par le clonage, tu dois pouvoir utiliser les Bookmark :
Avant de faire ton FindFirst, tu "bookmark" l'enregistrement sur lequel tu es.
Tu fais ton FindFirst et ton insersion ou mise à jour, puis, tu rappelles ton bookmark pour te replacer là où tu étais avant de faire le MoveNext.
Regarde dans l'aide comment fonctionne le Bookmark

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
DAVIMIKA Messages postés 118 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 10 janvier 2014
9 janv. 2010 à 15:14
Re Bonjour Jack

J'ai ajouté Bookmark en fonction de ce que j'ai compris :

'--- Trouvé NoMatch on met à jours
        rsFormaListe.Edit
      End If
          rsFormaListe("réfActivitéListe") = Me.txtRéfActivitéListe
          rsFormaListe("réfActivitéOption") = Val(Me.cmbOption)
          rsFormaListe("réfFormationListe") = Val(Me.cmbFormation)
          lngCodeRéf = rsFormaListe("RéfFormationActivitéListe")
      rsFormaListe.Update
   strSignet = rsFormaListe.Bookmark
   Debug.Print strSignet


Le debug.print me donne ? comme valeur

Est-ce que le Bookmark est bien placé ?


A+

Salutations.
0
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
9 janv. 2010 à 15:56
Non, à mon avis, le Bookmark doit être mémorisé avant de faire un FindFirst puis il faut le remettre avant de faire le MoveNext, histoire de ne pas perdre "l'index" sur lequel on est en train de faire la boucle.
Je ne pense pas qu'on puisse afficher un Bookmark, ou alors il renverra un simple chiffre ? je ne sais pas.
Pas d'exemple dans l'aide de Bookmark ?

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
0
DAVIMIKA Messages postés 118 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 10 janvier 2014
9 janv. 2010 à 19:02
Bonsoir Jack

J'ai essayer le Bookmark avant FindFirt et après
movenext mais sa boucle toujour.

Salutations
0
DAVIMIKA Messages postés 118 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 10 janvier 2014
9 janv. 2010 à 19:36
Re

il faut lire et avant movenext.

Salutations
0
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
10 janv. 2010 à 02:59
Oui, c'était bien ce que j'avais écrit : Avant, pas après le MoveNext.
0
DAVIMIKA Messages postés 118 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 10 janvier 2014
10 janv. 2010 à 11:10
Bonjour Jack,

Mais le problème reste entier ça boucle toujour,

Salutations
0
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
10 janv. 2010 à 11:56
Récapitulons :

Do While Not rs.EOF
  mémo = rs.Bookmark 
  utilisation de rs.FindFirst
  rs.Bookmark = mémo
  rs.MoveNext
Loop

et ça, ça ne marche pas ?

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
0
DAVIMIKA Messages postés 118 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 10 janvier 2014
10 janv. 2010 à 14:52
Re Bonjour Jack,

Non ça ne marche pas, pour plus de clarté je remet le code:

Private Sub BtnValider_Click()
On Error GoTo GestionErreur
 Dim varSignet As Variant
     Set db = CurrentDb()
            
'--- Intérogation de rsFormaListe
     Set rsFormaListe = db.OpenRecordset("tbl Formations-Activités-Liste", dbOpenDynaset)
   
'--- Intérogation de rsFormation
     Set rsFormation = db.OpenRecordset("tbl Formations", dbOpenDynaset)
   
'--- Test sur base vide
     If rsFormaListe.RecordCount = 0 Then
        rsFormaListe.AddNew
          rsFormaListe("réfActivitéListe") = Me.txtRéfActivitéListe
          rsFormaListe("réfActivitéOption") = Val(Me.cmbOption)
          rsFormaListe("réfFormationListe") = Val(Me.cmbFormation)
          lngCodeRéf = rsFormaListe("RéfFormationActivitéListe")
          
        rsFormation.AddNew
          rsFormation("réfAnimateur") = Nz(TxtRéfAnimateur.Value, 0)
          rsFormation("DatesDu") = Nz(txtDateDu.Value)
          rsFormation("DatesAu") = Nz(txtDateAu.Value)
          rsFormation("réfFormationActivitéListe") = lngCodeRéf
          rsFormaListe.Update
          rsFormation.Update
     End If
     
'--- Boucle sur la table rsFormaliste
     Do While Not rsFormaListe.EOF

'--- Définition du signet
     varSignet = rsFormaListe.Bookmark
    
'--- Recherche si l'enregistrement est trouvé
     strCritereA = "[RéfActivitéListe]=" & Val(Me.txtRéfActivitéListe) & " And " & _
                             "[RéfActivitéOption]=" & Val(Me.cmbOption) & " And " & _
                              "[RéfFormationListe]=" & Val(Me.cmbFormation)
     rsFormaListe.FindFirst strCritereA
    
'--- Test sur NoMatch
     If rsFormaListe.NoMatch Then
        rsFormaListe.AddNew
        
      Else
      
 '--- Trouvé NoMatch on met à jours
        rsFormaListe.Edit
      End If
          rsFormaListe("réfActivitéListe") = Me.txtRéfActivitéListe
          rsFormaListe("réfActivitéOption") = Val(Me.cmbOption)
          rsFormaListe("réfFormationListe") = Val(Me.cmbFormation)
          lngCodeRéf = rsFormaListe("RéfFormationActivitéListe")
      rsFormaListe.Update
      
'--- Maj et Ajout dans la tbl rsFormation
         
'--- Recherche si l'enregistrement est trouvé
     strCritereB = "[RéfFormationActivitéListe]=" & rsFormaListe![RéfFormationActivitéListe]
     
     rsFormation.FindFirst strCritereB
      
'--- Non trouvé NoMatch on ajoute
     If rsFormation.NoMatch Then
          rsFormation.AddNew
          
     Else
      
'--- Trouvé NoMatch vau on met à jours
        rsFormation.Edit
     End If
         rsFormation("réfAnimateur") = Nz(TxtRéfAnimateur.Value, 0)
         rsFormation("DatesDu") = Nz(txtDateDu.Value)
         rsFormation("DatesAu") = Nz(txtDateAu.Value)
         rsFormation("réfFormationActivitéListe") = lngCodeRéf
      rsFormation.Update
      
      'Maintien du Signet
      varSignet = rsFormaListe.Bookmark
      
      rsFormaListe.MoveNext
     Loop
 
'--- Màj du sous formulaire
     Forms![frm Màj Formations]![frm Màj Formations-sfm].Requery
     
'--- Ferme les objet
     rsFormaListe.Close: Set rsFormaListe = Nothing
     rsFormation.Close: Set rsFormation = Nothing
     db.Close: Set db = Nothing

GestionErreur:

End Sub



A+


Salutations.
0
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
10 janv. 2010 à 16:52
Reflechis !

      'Maintien du Signet
      varSignet = rsFormaListe.Bookmark   ' NON ! 
         ' Tu ne veux pas mémoriser le bookmark mais le repositionner :
      rsFormaListe.Bookmark = varSignet
         ' Il va falloir que tu apprennes à lire ce qu'on écrit !!
      rsFormaListe.MoveNext
     Loop
0
DAVIMIKA Messages postés 118 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 10 janvier 2014
10 janv. 2010 à 21:13
Bonsoir,

Ok je vais essayer de m?appliquer,

Les modifications apportées font que le code ne boucle plus sans fin, mais
J'ai un problème quand même.

Lorsque je fais un 1er enregistrement sur l'animateur 1 j'ai bien les enregistrements suivant les deux premières photos des tables. Si je choisis l'animateur 2 il ne se rajoute pas et prend la place de l'animateur 1 suivant la troisième photo des tables.
La quatrième photo est celle que je devrais obtenir, et que j'ai faite manuellement.

Je pense qu'il s'agit du strcritèreB
strCritereB = "[RéfFormationActivitéListe]=" & rsFormaListe![RéfFormationActivitéListe
]

Jj'ai essayé sans succès celui-ci :

rsFormation.FindFirst "[RéfFormationActivitéListe]=" & rsFormaListe![RéfFormationActivitéListe] & " and " & _
                     rsFormation("réfAnimateur") = Nz(TxtRéfAnimateur.Value, 0)

Ci-joint le lien des photos des tables

http://cjoint.com/?bkvd78ZiTs

Salutations
0
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
11 janv. 2010 à 02:00
C'est quoi ta fonction Nz ?
Apprends à débuguer ton code en pas à pas avec les touches F8 et F9 : Tu pourras suivre l'évolution du contenu de tes variables.

La section "Test sur base vide" ne sert à rien puisque, de toute façon, tu fais la recherche ensuite.

Un truc me gène :
Après avoir cherché avec ton critère A, tu crées ou édites l'enregistrement correspond, puis tu mémorises dans lngCodeRéf le contenu du champ RéfFormationActivitéListe.
Or, en cas d'ajout d'enregistrement, cette valeur est inconnue, donc vaut 0.
Donc après, est-ce que cela a un impact ?
A toi de débuguer et comprendre ce qui se passe, avec quelles valeurs ...

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
0
DAVIMIKA Messages postés 118 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 10 janvier 2014
11 janv. 2010 à 12:14
Bonjour Jack

La section "Test sur base vide" ne sert à rien puisque

Oui mais lorsque les bases sont vides les premiers enregistrements Ne se ceér pas.

Test:
Lorsque je crée un 2ème animateur j'ai ces valeurs :

Do While Not rsFormaListe.EOF : 
Faux

Debug.Print strCritereA :
[RéfActivitéListe]=5 And [RéfActivitéOption]=1 And [RéfFormationListe]=1

If rsFormaListe.NoMatch Then
Vrai

Le code passe par
rsFormaListe.AddNew

et l'enregistrement se crée bien dans la table puis

Debug.Print lngCodeRéf :
99

Debug.Print strCritereB :
[RéfFormationActivitéListe]=89


If rsFormation.NoMatch Then
Faux

Et passe à
rsFormation.Edit


et remplace l'ancien enregistrement qui passe
de RéfFormationActivitéListe]=89 à 99 sans créer le nouvel enregistrement.

A+
Salutations
0
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
11 janv. 2010 à 12:45
"Oui mais lorsque les bases sont vides les premiers enregistrements Ne se ceér pas"
Je suis d'accord, mais dans ce cas, il ne faut pas exécuter les lignes qui suivent puisque tu as déjà rempli les tables !
Il faudrait faire une structure complète :
If rsFormaListe.RecordCount = 0 Then
  ' Tes AddNew
Else
  Do While Not rsFormaListe.EOF
    ' Tes recherches
  Loop
End If

---------------------------------------------------------------------
Oui, bah c'est bien ce que ton code fait :
Tu recherches 89
Il le trouve
Tu le remplaces ensuite par lngCodeRéf qui vaut 99

Que veux-tu que je te dise ?
Ton code fait exactement ce que tu lui dis de faire ...

Est-ce que, par hasard, il ne serait pas plus judicieux de faire la recherche B avec lngCodeRéf plutôt qu'avec rsFormaListe![RéfFormationActivitéListe]
0
DAVIMIKA Messages postés 118 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 10 janvier 2014
11 janv. 2010 à 13:59
Re Bonjour,

Est-ce que, par hasard, il ne serait pas plus judicieux de faire la recherche

J'ai essayé sans résultat.

Je pense que je suis partie sur une mauvaise piste avec ce code, car moi je voudrais que lorsque un enregistrement comme :

[RéfActivitéListe]=5 And [RéfActivitéOption]=1 And [RéfFormationListe]=1 et trouvé on crée un enregistrement dans la table formation et l'on met la valeur :
RéfFormationActivitéListe: 99 de la tbl Formations-Activités-Liste dans le champ :
RéfFormationActivitéListe de la table formations.

Mais ça je n'arrive pas à le faire, et je suis vraiment bloquer.

A+

Salutations
0
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
11 janv. 2010 à 15:23
Si, ton principe est bon, mais ne connaissant pas le détail de ton projet, n'ayant pas les données sous la main et ne connaissant pas tous les liens entre tes tables, ce qu'elles représentent ..., je ne peux que te suggérer des tests à faire, mais c'est à toi de les faire.
Tu as parfaitement reporté le comportement de ton appli lors du passage d'ajout de la 2ème fiche : A toi de suivre le programme, de juger si tel ou tel test est correctement fait, s'il faut les compléter, s'il en faut d'autres, ...
En debug, tu peux modifier tes instructions pendant le run : Profites-en pour corriger.
Tu peux aussi déplacer le fil du programme si tu veux qu'il reparte plus haut ou plus bas (voir les Menus)
Tu peux aussi profiter de la fenêtre de debug (Ctrl-G) pour afficher le contenu de variables ou tout autre indice.
A toi de faire.

Si tu es perdu, recommence à zéro : met ce code dans une fausse Sub pour le garder sous le coude et recommence complètement cette partie de code, repense aux tests que tu as besoin de faire.
Dès que tu tapes un If, mets tout de suite un Else et un End If : Ca t'obligera à penser à ce qu'il faut faire si le test n'est pas bon (utile ou pas, tu verras pour chaque cas).
Par exemple : Actuellement, tu fais une boucle Do-Loop pour scanner tous tes enregistrements.
Question : Est-ce utile puisque tu fais une recherche et que tu traites le cas "existe" / "existe pas" ?

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
0
Rejoignez-nous