Ajouter un paramètre dans une boucle avec MsgBox

Résolu
Bonjour,

Voici mon code :

Dim Rollback As Integer, I As Long, DL As Long
    
    DL = Range("B65536").End(xlUp).Row

If MsgBox("Voulez-vous vérifier la TVA sur les débits?", vbYesNo, "Vérif RAN TVA débits") = vbYes Then
        For I = 13 To DL
            If Sheets(1).Range("D" & I) = "RAN" Or Sheets(1).Range("D" & I) = "OD" Then
                If Left(Sheets(1).Range("B" & I), 3) <> 403 Then
                    Sheets(1).Range("B" & I).Select
                    retval = MsgBox("Le fournisseur suivant (tiers : " & Range("B" & I) & " ) est-il soumis à TVA sur les débits?", vbYesNoCancel, "Vérif TVA débits")
                    If retval = vbNo Then Sheets(1).Range("N" & I) = ""
                    If retval = vbYes Then
                        Sheets(1).Range("N" & I) = Sheets(1).Range("K" & I)
                        If Sheets(1).Range("B" & I) = Sheets(1).Range("B" & I + 1) Then Sheets(1).Range("N" & I + 1) = Sheets(1).Range("K" & I + 1)
                        Rollback = I
                  ElseIf retval = vbNo Then Rollback = I
                  ElseIf retval = vbCancel Then
                        If MsgBox("Faite ok pour revenir à la facture : (tiers : " & Range("B" & Rollback) & " )  ou cancel pour annuler", vbOKCancel, "Confirmer le choix") = vbOK Then
                             I = Rollback - 1
                            Sheets(1).Range("N" & Rollback) = ""
                         Else
                             Exit For
                         End If
                     End If
                End If
            End If
      Next I
End If


En fait, la première MsgBox lance la suite du code. Ensuite, à chaque ligne I, la cellule ("B" & I) est sélectionnée. La MsgBox suivante sert à demander si effectivement, le tiers sélectionné est soumis à la TVA sur les débits ou non. Si oui, alors on remplit la cellule en face (colonne K) avec les données dans la colonne N.
Ensuite, le code précise qu'on peut annuler l'action et revenir à la ligne précédente.

Voici mon problème. Je souhaiterais que si sur les lignes après I, les cellules de la colonne B sont les mêmes (le tiers est toujours le même), le code ne repose pas la question pour chaque ligne mais que toutes ces lignes où le tiers est le même (toujours avec la condition au départ D=RAN ou D=OD) soient remplies directement. Et qu'ensuite on passe à la ligne I + "le nombre de lignes où le tiers est le meme".
En gros, qu'on passe au tiers suivant. (Sélection + la MsgBox qui pose la question de savoir si le tiers est soumis à la TVA sur les débits.

La ligne que j'ai rajouté et qui ne fait pas ce que je veux :

If Sheets(1).Range("B" & I) = Sheets(1).Range("B" & I + 1) Then Sheets(1).Range("N" & I + 1) = Sheets(1).Range("K" & I + 1)


Merci d'avance.

8 réponses

Résumé de la discussion

Plusieurs échanges portent sur une macro VBA qui vérifie la TVA sur les débits et, lorsque D vaut RAN ou OD, déclenche une confirmation et remplit N selon K. L'objectif est que, pour les lignes suivantes dont le même tiers apparaît, la question TVA ne soit posée qu'une fois et que le remplissage N soit appliqué jusqu'au changement de tiers. Plusieurs propositions évoquent d'encapsuler la logique dans une procédure dédiée et d'utiliser des variables memtiers et NT pour regrouper les lignes par tiers et propager le remplissage sans relancer la question. En dernier, les échanges indiquent que l'ampleur du regroupement dépend de la détection du changement de tiers et que l'annulation doit réinitialiser l'ensemble des lignes du bloc concerné.

Bobot (l’IA à votre service)
  1. Bonjour,

    A tester, je n'ai pas vos donnees:

    Sub test()
    Dim Rollback As Integer, I As Long, DL As Long
        
        DL = Range("B65536").End(xlUp).Row
    
        If MsgBox("Voulez-vous vérifier la TVA sur les débits?", vbYesNo, "Vérif RAN TVA débits") = vbYes Then
            For I = 13 To DL
                If (Sheets(1).Range("D" & I) = "RAN" Or Sheets(1).Range("D" & I) = "OD") And Left(Sheets(1).Range("B" & I), 3) <> 403 Then
                    'Sheets(1).Range("B" & I).Select
                    retval = MsgBox("Le fournisseur suivant (tiers : " & Range("B" & I) & " ) est-il soumis à TVA sur les débits?", vbYesNoCancel, "Vérif TVA débits")
                        If retval = vbYes Then
                            memtiers = Sheets(1).Range("B" & I)
                            NT = I
                            Do While Sheets(1).Range("B" & NT) = memtiers
                                If (Sheets(1).Range("D" & I) = "RAN" Or Sheets(1).Range("D" & I) = "OD") And Left(Sheets(1).Range("B" & I), 3) <> 403 Then
                                    Sheets(1).Range("N" & NT) = Sheets(1).Range("K" & NT)
                                    NT = NT + 1
                                End If
                            Loop
                            'Rollback = I            '?????????????????
                            I = NT - 1
                      ElseIf retval = vbNo Then Sheets(1).Range("N" & I) = "": Rollback = I
                      ElseIf retval = vbCancel Then
                        If MsgBox("Faite ok pour revenir à la facture : (tiers : " & Range("B" & Rollback) & " )  ou cancel pour annuler", vbOKCancel, "Confirmer le choix") = vbOK Then
                            I = Rollback - 1
                            Sheets(1).Range("N" & Rollback) = ""
                        Else
                            Exit For
                        End If
                    End If
                End If
          Next I
        End If
    End Sub
    0
    1. Bonjour et merci pour cette réponse.

      Après avoir testé, le code marche plutôt bien à 2 détails près.

      1:/ La ligne Sheets(1).Range("B" & I).Select était utile car elle permet tout au long du code de suivre les lignes concernées en sélectionnant la cellule. Il faut avoir l'impression de parcourir la feuille avec l'écran qui suit. (certaines lignes sont parfois spéciales, le tiers seul ne suffit pas).

      2:/Les lignes suivantes se remplissent en effet si le tiers est le même. Cependant, il aurait fallut que seules les lignes suivantes dont le tiers est le même ET dont la colonne D = "RAN" ou "OD" se remplissent.

      Merci 1000 fois pour votre aide en tout cas.

      Cordialement.
      0
    2. @KuartzRe,

      Do While Sheets(1).Range("B" & NT) = memtiers
      vous entrez dans la boucle si tiers egaux

      et cette ligne dans le
      do while
      doit correspondre a votre demande, c'est la meme qu'au debut:

      If (Sheets(1).Range("D" & I) = "RAN" Or Sheets(1).Range("D" & I) = "OD") And Left(Sheets(1).Range("B" & I), 3) <> 403 Then
      0
    3. Effectivement. Pourtant si je répond OUI à la MsgBox, j'ai un tiers qui se remplit complètement sur toutes les lignes alors qu'il n'y a pas RAN ou OD dans la colonne D. Je comprend pas...
      0
    4. Fichier anonymé simplifié : https://www.cjoint.com/c/EGxoqTK5adf

      Vous constaterez que même si il n'y a pas RAN ou OD devant l'écriture, les cases se remplissent quand même si je répond OUI.
      0
    5. @KuartzRe,

      Eh oui, je n'ai pas entierement modifie la fameuse ligne:

      If (Sheets(1).Range("D" & I) = "RAN" Or Sheets(1).Range("D" & I) = "OD") And Left(Sheets(1).Range("B" & I), 3) <> 403 Then
      

      alors que c'est comme ca vu que je change de pointeur:

      If (Sheets(1).Range("D" & NT) = "RAN" Or Sheets(1).Range("D" & NT) = "OD") And Left(Sheets(1).Range("B" & NT), 3) <> 403 Then
      
      0
  2. Bonjour,

    Je pense qu'on est pas loin de la vérité. Mais le bouton annuler est fait pour aux cellules que l'on a remplit juste avant. Or, si vous essayez la macro et que vous faites "annuler" puis "ok", on ne revient pas à la ligne précédente. Si vous voulez le but, c'est que j'ai 1000 lignes à vérifier comme ça. Si je me plante en cliquant trop vite sur OK, je veux pouvoir revenir à "l'événement" d'avant.

    Merci de votre aide en tout cas.
    0
    1. Bonjour,

      Vous demandez de faire un traitement par lot de "tiers" et vous voulez revenir a une ligne !!

      Vous pourriez mettre un fichier a dispo un peu plus complets avec des tiers differents que je vois comment c'est empiler ??
      0
    2. Vous avez raison. Je veux faire un traitement par lot de tiers. Et revenir au tiers précédent. Sauf que là, le code ne revient pas au tiers précédent. Je met OUI pour un tiers, le code remplit la colonne concernée pour ce tiers. Je me suis trompé. Je veux revenir à ce même tiers et mettre NON cette fois pour que la colonne concernée pour ce tiers n'affiche rien.

      Je vous fais un fichier complet, le temps de l'anonymer. Il y a un avantage, c'est que les tiers sont triés. Il n'y en aura pas ailleurs dans la feuille. Je vous fais ça rapidement.
      0
    3. @KuartzNouveau fichier : https://www.cjoint.com/c/EGBjzEygZff

      Attention : Les AAAAA au début n'ont pas le même nombre de lettres qu'à la fin, ce ne sont pas les mêmes tiers (désolé, défaut d'imagination...)
      0
    4. @KuartzRe,

      Je recupere le fichier et le pense (un ton en dessous de j'imagine) avoir trouver
      0
  3. Je vais essayer de faire très mathématique comme demande.

    Soit en colonne B le nom du tiers.

    Soit en colonne N, la TVA sur les débits.

    Soit en colonne D, le code journal (ACH, RAN, OD, ...)

    Si colonne D = RAN ou OD alors MsgBox "le Tiers "colonne D" est-il soummis à la TVA sur les débits?"

    Si OUI : Remplir toutes les cellules de la colonne N dont le tiers en colonne D est celui en question en faisant le calcul N = K.

    Si NON : Ne rien mettre dans toutes les cellules de la colonne N dont le tiers en colonne D est celui en question.

    Si ANNULER : Nouvelle MsgBox
    - Si OK : Revenir à "l'événement précédent", c'est à dire à la vérification du tiers précédent. En gros revenir à la MsgBox d'avant.
    - Si ANNULER : Passer à la suite du code en quittant la vérification de la TVA sur les débits.

    Si ce n'est pas clair, n'hésitez pas à me dire ce qui ne l'est pas.

    Merci encore.
    0
    1. Re,

      testez ce fichier: https://www.cjoint.com/c/EGBjTTSkMXf

      ou j'ai colle l'onglet de celui que vous avez envoye sans mot de passe pour le VBA
      0
      1. Quelle macro dois-je tester?
        0
      2. Si vous testez la macro TEST, répondez non jusqu'au tiers CCCCCC. Là, répondez oui, puis annulez, puis OK et là on revient au tiers d'avant. Ca fonctionne. Là répondez non, seule la première ligne du tiers CCCCCC s'est effacée...

        Pourtant, si je me penche sur votre code, il ne devrait pas se comporter comme ça. Puisque le Do While est bien présent également sur le le retval No...
        0
      3. @KuartzRe,

        Y a bien deux lignes avec CCCCC mais une seule avec RAN !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        0
      4. Pardon je viens de dire une bêtise. Tout marche niquel comme je voulais bravo :)

        Après retest, effectivement les lignes dont le tiers est le même s'effacent bien toute si je reviens en arrière et que je fais "NON".

        Merci infiniement. Il me reste maintenant à adapter un MsgBoxPerso là dessus. Je vais essayer.

        J'utilise http://www.mdf-xlpages.com/modules/publisher/item.php?itemid=58
        0
      5. @KuartzJ'essaye mais ça ne marche pas du tout....

        Sub TEST()
        
        Dim DL As Long
            
        DL = Range("A65536").End(xlUp).Row
         
        Dim Rollback As Integer, memligne As Long
        
        If MsgBox("Voulez-vous vérifier la TVA sur les débits?", vbYesNo, "Vérif RAN TVA débits") = vbYes Then
                For I = 13 To DL
                    Rollback = I
                    Sheets(1).Range("B" & I).Select
                    If (Sheets(1).Range("D" & I) = "RAN" Or Sheets(1).Range("D" & I) = "OD") And Left(Sheets(1).Range("B" & I), 3) <> 403 Then
                        memtiers = Sheets(1).Range("B" & I)
                        retval = MsgBoxPerso("Le fournisseur suivant (tiers : " & Range("B" & I) & " ) est-il soumis à TVA sur les débits?", "Vérif TVA débits", vQuestion, "Oui|Non|Tiers précédent|Arrêter la vérif")
                        Select Case retval
                        Case 1
                            memligne = I
                            NT = I
                            Call majour_Debits(NT, I, retval, memtiers, memligne, Rollback)
                        Case 2
                            NT = I
                            Call majour_Debits(NT, I, retval, memtiers, memligne, Rollback)
                        Case 3
                            If memligne > 0 Then
                                    I = memligne
                                    NT = I
                                    Call majour_Debits(NT, I, retval, memtiers, memligne, Rollback)
                            End If
                        Case 4
                             Exit For
                        End Select
                    End If
                Next I
        End If
        End Sub
        
        Sub majour_Debits(NT, I, retval, memtiers, memligne, Rollback)
            Application.ScreenUpdating = False
            Do While Sheets(1).Range("B" & NT) = memtiers
                If (Sheets(1).Range("D" & NT) = "RAN" Or Sheets(1).Range("D" & NT) = "OD") And Left(Sheets(1).Range("B" & NT), 3) <> 403 Then
                    If retval <> vbYes Then
                        Sheets(1).Range("N" & NT) = ""
                    Else
                        Sheets(1).Range("N" & NT) = Sheets(1).Range("K" & NT)
                    End If
                End If
                NT = NT + 1
            Loop
            I = NT - 1
            Rollback = I
            Application.ScreenUpdating = True
        End Sub
        


        Je sais pas comment adapter le truc dans "majour_Debits". Comment je peux traduire : "If retval <> vbyes Then" avec la méthode du Select Case?
        0
    2. Re,

      If memligne > 0 Then

      manquait le
      end if


      et du coup, un end if en trop avant le next

      https://www.cjoint.com/c/EGBqRtBTUkf

      retestez tout
      0
      1. Bravo, bravo, bravo. Enfin, tout marche :) Que ça fait plaisir !

        Allez je vous embête encore avec 2 petites questions :

        1:/ Est-il possible de faire en sorte que si je fasse tiers précédent sur le premier tiers, le code me fasse rester sur cette première ligne, ce qui serait logique. (Pas de prise de tête, si c'est trop compliqué, vous me le dites, je laisse tomber)

        2:/ Un peu plus important : Est-il possible de recentrer ma MsgBoxPerso au milieu de l'écran quand elle apparaît? Parce que bon, je suis en double écran et elle apparaît sur l'autre écran...

        Merci encore pour votre aide.
        0
      2. Merci beaucoup :) Je teste.
        0
      3. La MsgBox apparaît toujours sur mon deuxième écran... Ca c'est vraiment lourd... Mais je ne pense pas qu'on puisse y faire grand chose. Certes, elle apparaît centrée mais sur le deuxième écran...

        Je vous remercie vraiment énormément pour tout ce que vous m'avez appris et pour l'immense aide apportée ainsi que pour le temps passé à ça.

        Je passe le sujet en résolu. Encore merci !
        0
      4. Je suis vraiment désolé, j'ai encore trouvé une erreur :s

        Si vous répondez non à la MsgBox, et que vous répondez "Tiers précédent" à la MsgBox suivante, le code revient au tiers précédent dont on a répondu Oui à la MsgBox.

        En gros, si la colonne N n'a pas été remplie, le code ne le considère pas comme un tiers où l'on peut revenir.
        0
    3. Bonjour,

      Je ne comprend pas trop là... Hier tout marchait parfaitement. Aujourd'hui, je fais "Tiers précédent" j'obtiens "Erreur définie par l'application ou par l'objet"...

      Des idées?
      0
      1. OK donc parfois le programme marche mais très souvent, j'obtiens "erreur définie par l'application ou par l'objet" en faisant "Tiers précédent".
        0