Boucle do while

jadami Messages postés 107 Statut Membre -  
yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   -
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

  1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 588
     
    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.
    0
  2. jadami Messages postés 107 Statut Membre
     
    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
    0
    1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588
       
      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.
      0
  3. jadami Messages postés 107 Statut Membre
     
    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
    0
    1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588
       
      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?
      0
  4. jadami Messages postés 107 Statut Membre
     
    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
    0
    1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588
       
      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.
      0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. jadami Messages postés 107 Statut Membre
     
    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
    0
    1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588
       
      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".
      0
  7. jadami Messages postés 107 Statut Membre
     
    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.
    0
    1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588
       
      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?
      0
  8. jadami Messages postés 107 Statut Membre
     
    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
    0
    1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588
       
      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.
      0