Boucle do while

Bonjour,

J’ai deux tables « tbl Adhérents » et « tbl chèques », je voudrais que lorsque
je supprime un enregistrement de la table chèque je décoche une case à cocher
de la « tbl adhérents ».

Dans mon cas le FindFirst peut contenir soit un enregistrement, soit deux enregistrements.

Le code ci-dessus semble tourner en boucle.
'--- Appel ouverture de la base
Set db = CurrentDb

'--- Intérogation de la tbl adhérent
Set rsAdh = db.OpenRecordset("tbl Adhérents", dbOpenDynaset)

'--- Intérogation de la tbl chèques
Set rsChq = db.OpenRecordset("tbl Chèques", dbOpenDynaset)<code>

Do While Not rsAdh.EOF

'--- Recherche si l'enregistrement existe
'rsChq.FindFirst "[NomFamille]=" & Chr(34) & rsAdh("NomFamille") & Chr(34) & " AND " & _
"[RegroupFamille]=" & CStr(rsAdh("RegroupFamille"))

rsChq.FindFirst "[NomFamille]=" & Chr(34) & txtNomFamille & Chr(34) & " AND " & _
"[RegroupFamille]=" & CStr(cmbRegroupFamille)

If rsAdh.NoMatch Then
rsChq.Delete
Else
End If

'--- Màj de la case a cocher paiement
rsAdh.Edit
rsAdh("paiement") = False
rsAdh.Update

rsAdh.MoveNext
Loop
Merci pour votre aide.

Salutations

7 réponses

  • Votes
  • Date
  • Date décroissante
  1. Contributeur
    bonjour,
    pourquoi écris-tu que ton code tourne en boucle? veux-tu dire qu'il ne fait pas ce que tu souhaites?
    FindFirst ne retourne, au mieux, qu'un seul enregistrement.
    bizarre de faire If rsAdh.NoMatch alors que tu n'as pas fait de find sur rsAdh.
    regarde bien ton code: il décoche inconditionnellement la case à cocher.
    1. Bonsoir yg_b,

      Merci pour ta réponse.

      "pourquoi écris-tu que ton code tourne en boucle? " "veux-tu dire qu'il ne fait pas ce que tu souhaites? "

      Oui il ne fait pas ce que je souhaite

      Pour rsAdh.NoMatch c'est bien rsChq.NoMatch

      NoMacth est toujours à vrai ce qui fait que le code boucle toujours sur la case à cocher
      et modifie toutes les cases.

      Je ne vois pas le problème, j'ai essayé ce code:

      If rsChq.NoMatch Then
      rsChq.Delete
      Else
      End If

      '--- Maj de la case a cocher paiement
      rsAdh.Edit
      rsAdh("paiement") = False
      rsAdh.Update

      rsAdh.MoveNext
      Loop


      Mais les enregistrements de la table Chèques sont supprimés et le code
      bloque sur rsChq.Delete avec le message "Aucun enregistrements en cours.

      Salutations
      1. Contributeur
        pourquoi fais-tu rsChq.Delete?
        pourquoi fais-tu deux FindFirst successifs?
        tu n'expliques ni ce que tu veux obtenir, ni comment tu penses le réaliser.
    2. Bonjour,

      « tu n'expliques ni ce que tu veux obtenir, ni comment tu penses le réaliser. »
      Dans la table j’ai deux types d’enregistrements :
      Un enregistrement (image tbl adhérents 1 et tbl chèques 1) qui correspondent aux personnes seules
      Deux enregistrements (image tbl adhérents 2 et tbl chèques 2) qui correspondent aux couples

      Je voudrais, lorsque je supprime soit l’un ou l’autre des enregistrements de la tbl Chèques, que la case à Cocher (Paiement) de la tbl Adhérents soit décochée.

      J’ai pensé qu’avec une boucle do while , un rsChq.Delete pour supprimer dans la tbl Chèques
      et un edit pour une mise à jour dans la tbl Adhérents cela pouvait se faire, mais voilà je n’y arrive
      pas. Peut-être une mauvaise méthode ?

      « pourquoi fais-tu deux FindFirst successifs? »
      Non je n’utilise qu’un seul « FindFirst » celui qui prend les valeurs des contrôles du formulaire, l’autre est inactif, mais peut-être est-ce une erreur de faire comme cela ?

      Salutations
      1. Contributeur
        eh bien, utilisons l'exemple que tu as montré.
        imaginons que ton code se met en route.
        quelles sont les valeurs de txtNomFamille et de cmbRegroupFamille?
        que souhaites-tu que ton code fasse?
        comme tu as modifié tn code, peux-tu le montrer à nouveau?
    3. Bonjour,

      «eh bien, utilisons l'exemple que tu as montré. »
      Dans l’exemple que j’ai montré il y a 3 adhérents,
      2 en couple (Réf Adhérents 2043 et 2044) et
      1 unique (réf Adhérents 2035)
      Tous les trois ont la case Paiement cochée (tbl Adhérents) et
      un enregistrement Chacun ( tbl Chèques)

      « que souhaites-tu que ton code fasse? »
      Dans le cas du couple (Voir image tbl chéques et tbl adhérents) :

      Tbl Chèques
      Il doit supprimer uniquement les chèques (Réf Adhérents 2043 et 2044).
      Tbl adhérents
      Et décocher les cases Paiement du couple (Réf Adhérents 2043 et 2044).

      Dans le cas d’une personne seule voir image :
      Tbl Chèques
      Il doit supprimer uniquement le chèque (Réf Adhérents 2035).
      Tbl adhérents
      Et décocher la case Paiement de la personne seule (Réf Adhérents 2035).

      « quelles sont les valeurs de txtNomFamille et de cmbRegroupFamille »
      Voir l’image des espions pour le cas de la personne seule)

      Au passage je m’aperçois que j’aurais dû ajouter Réf Adhérent dans le FindFirst

      '--- Appel ouverture de la base
      Set db = CurrentDb

      '--- Intérogation de la tbl adhérent
      Set rsAdh = db.OpenRecordset("tbl Adhérents", dbOpenDynaset)

      '--- Intérogation de la tbl chèques
      Set rsChq = db.OpenRecordset("tbl Chèques", dbOpenDynaset)

      Do While Not rsAdh.EOF

      '--- Recherche si l'enregistrement existe
      rsChq.FindFirst "[NomFamille]=" & Chr(34) & rsAdh("NomFamille") & Chr(34) & " AND " & _
      "[RegroupFamille]=" & CInt(rsAdh("RegroupFamille")) & " AND " & _
      "[RéfAdhérent]=" & CInt(rsAdh("RéfAdhérent"))

      If Not rsChq.NoMatch Then

      rsChq.Delete
      MsgBox "ok"

      '--- Màj de la case a cocher paiement
      rsAdh.Edit
      rsAdh("paiement") = False
      rsAdh.Update
      End If
      rsAdh.MoveNext
      Loop

      Mais ce code termine la boucle et ne donne jamais NoMacth à faux .

      Merci pour votre aide ;

      Salutations
      1. Contributeur
        plus je te lis, moins je comprends.
        pourquoi as-tu supprimé txtNomFamille et de cmbRegroupFamille?
        ajoute "option explicit" en début de module.
        partage ton code complet. qu'est-ce qui déclenche l'exécution de ce code?
        au lieu de:
        rsChq.FindFirst "[NomFamille]=" & Chr(34) & rsAdh("NomFamille") & Chr(34) & " AND " & _ 
        "[RegroupFamille]=" & CInt(rsAdh("RegroupFamille")) & " AND " & _ 
        "[RéfAdhérent]=" & CInt(rsAdh("RéfAdhérent"))

        fais plutôt:
        dim critere as string
        critere =  "[NomFamille]=" & Chr(34) & rsAdh("NomFamille") & Chr(34) & " AND " & _ 
        "[RegroupFam]=" & CInt(rsAdh("RegroupFamille")) & " AND " & _ 
        "[RéfAdhérent]=" & CInt(rsAdh("RéfAdhérent"))
        rsChq.FindFirst critere

        partage la valeur de la variable critere.
    4. Désolé si je n’arrive pas à me faire comprendre, je reprends ce que j’avais dit au premier message
      et te remercie de ta patience.

      «
      J’ai deux tables « tbl Adhérents » et « tbl chèques », je voudrais que lorsque
      Je supprime un enregistrement de la table chèques je décoche une case à cocher
      De la « tbl adhérents
      »

      Maintenant, en faisant debug.print sur le critère tous les enregistrements apparaissent et l’image suivante
      montre entouré de rouge celui que je voulais supprimer .

      Le code se déclenche uniquement par un click sur une case à coché du formulaire/

      Salutations
      1. Contributeur
        tout fonctionne bien ou tu as encore un soucis? lequel?
        tu n'as pas encore mentionné le formulaire: le code doit-il utiliser des données du formulaire?
        que doit faire le code quand la case à cocher est cliquée?
        ce serait plus clair si tu n'utilisais pas "je" pour ce que le code doit faire. tu pourrais par exemple écrire "quand l'utilisateur clique, le code doit supprimer tous les chèques".
    5. Oui j'ai encore du souci puisque le code parcourt les enregistrements sans déclencher d'action.

      Oui en effet quand l'utilisateur clique, le code doit supprimer tous les chèques affichés dans le sous formulaire et mettre à jour la case paiement de la table Adhérents".

      Plus tard je posterai une image du form avec son sfrm.
      1. Contributeur
        as-tu utilisé la valeur montré par debug.print critere pour faire une requête?
        tu écris que le code doit supprimer tous les chèques affichés dans le sous formulaire. rien n'est prévu dans le code pour consulter le sous formulaire. le code ne devrait-il pas commencer pas récupérer tous ces chèques?
    6. Bonsoir yg_be,

      Voilà ce que j’ai fait, je ne sais pas si c’est la bonne méthode, mais j’ai le résultat que je souhaitais.

      A savoir :

      1er cas.
      L’utilisateur choisit une personne, ce qui fait apparaître un enregistrement dans le sous formulaire.
      Par un click sur un bouton l’enregistrement est supprimé de la table chèques et la case paiement de la table Adhérents est décochée

      2éme cas.
      L’utilisateur choisit un couple, ce qui fait apparaître deux enregistrements dans le sous formulaire.
      Par un click sur un bouton les deux enregistrements sont supprimés de la table chèques et les cases paiement de la table Adhérents sont décochées.

      Au passage je fais mon « mea culpa » car en écrivant ces deux cas je m’aperçois que si j’avais
      dès le début expliqué de cette façon on se serait épargné bien de la peine.

      En tout cas je te remercie de nouveau pour ton aide et ta patience.

      '--- Ouverture de la base
      Set db = CurrentDb

      '--- Interrogation de la tbl adhérent
      rq = "SELECT [tbl Adhérents].*, [tbl Adhérents].NomFamille, [tbl Adhérents].RegroupFamille" & _
      " FROM [tbl Adhérents]" & _
      " WHERE [tbl Adhérents].NomFamille=" & Chr(34) & lstr_NomFamille & Chr(34) & _
      " And [tbl Adhérents].RegroupFamille=" & lstr_RegroupFamille & ";"
      'Debug.Print rq

      Set rsAdh = db.OpenRecordset(rq, dbOpenDynaset)

      '--- Interrogation de la tbl chèques
      rq = "SELECT [tbl Chèques].*, [tbl Chèques].NomFamille, [tbl Chèques].RegroupFamille" & _
      " FROM [tbl Chèques]" & _
      " WHERE [tbl Chèques].NomFamille=" & Chr(34) & lstr_NomFamille & Chr(34) & _
      " And [tbl Chèques].RegroupFamille=" & lstr_RegroupFamille & ";"
      'Debug.Print rq

      Set rsChq = db.OpenRecordset(rq, dbOpenDynaset)

      '--- Boucle sur la tbl adhérents
      Do Until rsAdh.EOF

      '--- Compte le nb d'enregistrement
      If rsChq.RecordCount <> 0 Then '3
      rsChq.Delete
      rsChq.MoveNext
      End If

      '--- Màj de la case a cocher paiement
      rsAdh.Edit
      rsAdh("paiement") = False
      rsAdh.Update
      rsAdh.MoveNext
      Loop

      '--- Màj du sous formulaire
      Forms(frm)(sfm).Requery

      '--- Fermetureet libèration des objects
      rsAdh.Close: Set rsAdh = Nothing
      rsChq.Close: Set rsAchq = Nothing
      Set db = Nothing


      Salutations
      1. Contributeur
        ton approche me semble très logique.
        je pense cependant qu'il vaut mieux faire deux boucles successives, une sur chaque requête. et traiter chaque table dans sa boucle.