VBA - Problème de Boucle et Répétition des Résultats

Bonjour à tous,

Je me présente rapidement Stéphane, je viens très régulièrement sur ce forum, plutôt en visiteur, et jusqu'à présent j'ai toujours réussit à me débrouiller avec vos explications et exemples. Mais dans le cas présent j'avoue que je bloque sérieusement sur un code.
(A noter qu'en code VBA j'ai plutôt un niveau "Dépatouilleur" que même débutant...)

Vous trouverez un exemple du fichier que je tente de mettre en place.

Les 2 colonnes concernées par ma recherche sont les E et H, avec en conditions :

- Si dans la Colonne E les cellules sont saisies avec la valeur "E" (ou vierge), alors j'envoi un mail

- Si dans la Colonne E les cellules sont saisies avec la valeur "E", et que leur pendant en colonne H contient une donnée, alors j'envoie un mail

- Si dans la colonne E les cellules sont saisies avec la valeur "E", mais que leur pendant en colonne H est vierge, alors j'affiche un message d'erreur.

J'arrive à créer ces conditions et résultats pour une seules et même ligne, mais dés lors que je veux répéter sur plusieurs lignes, ou mettre une boucle, alors les résultats se multiplient autant de fois que de ligne à regarder.

Auriez vous une idée ? (Dans le cas du fichier, je suis revenu à un code relativement simple, du moins je pense, qui ne reprend qu'une seule ligne)

En vous remerciant par avancez de votre aide.

8test-2.xlsm (23.45 Ko)

Bonjour et bienvenue,

Votre code est très correct pour quelqu'un qui se considère comme débutant. Si j'ai bien compris (pas sur), vous souhaitiez boucler sur le tableau visible dans la macro Vérification_Données. Ci-après une proposition et quelques notes.

Mais je ne sais pas comment marche la macro d'envoi de mails, et si elle est générique ou doit s'adapter à la ligne parcourue. Il me semble que non donc je ne l'ai pas modifiée.

Sub Vérification_Données()
  Dim derniereLigne As Long
  derniereLigne = 28

  Dim numeroLigne As Long
  Dim target As Range

  ' c'est important, voir essentiel
  ' car si vous avez une autre feuille active la macro va faire n'importe quoi
  Sheets("Saisie").Activate

  For numeroLigne = 9 To derniereLigne
    Set target = ActiveSheet.Range("E" & numeroLigne)
    If target.Value <> "E" Then
      envoi_mail    ' pas besoin de "Call", c'est une instruction obsolete
    ElseIf target.Value = "E" And Not IsEmpty(Range("H" & numeroLigne)) Then
      envoi_mail
    ElseIf target.Value = "E" And IsEmpty(Range("H" & numeroLigne)) Then
      MsgBox "un E doit obligatoirement faire l'objet d'un H", vbExclamation
      ' utiliser Activate plutot que Select force a ne selectionner qu'un element
      ' c'est un détail mais pour votre cas c'est plus correcte
      Sheets("Saisie").Activate
      Range("H" & numeroLigne).Activate
    End If

  Next numeroLigne

End Sub

Pensez à déclarer vos variables (Dim), cela vous donnera accès à l'autocomplétion via IntelliSense.

Faites attention, par défaut écrire "Range(blablabla)" fait référence à la feuille active... qui n'est pas toujours celle sur laquelle on travaille ! Il est préférable d'écrire Thisworkbook.Worksheets("nomfeuille").Range(blablabla). C'est plus long mais ca ne bugue pas.

Déjà un très grand merci pour ce retour très rapide, et surtout pour ces petites annotations dans votre Code qui me permettent de comprendre (super sympas)

En revanche cela ne fonctionne pas comme souhaité, les actions se répètent toujours à chaque contrôle de ligne (28 lignes, 28 Contrôles, 28 actions).

Mais en même temps je m'aperçois que je n'ai pas été suffisamment clair dans ma recherche.

De façon très simpliste, je cherche :

1- A ce que le fichier s'envoi automatiquement par mail dés lors que l'on clique sur "envoyer" (un seul mail envoyé, quelque soit le nombre et la condition recherchée/trouvée) - Le code pour l'envoi du mail est écrit, je n'ai pas de souci sur ce point.

2- SAUF si dans la colonne E les cellules sont saisies avec la valeur "E", mais que leur pendant en colonne H est vierge (Contrôle E9 par rapport à H9, E10/H10, etc.)

Dans se second cas, pas d'envoi de mail, mais un blocage et une alerte MsgBox. Ce blocage et alerte (dans la même idée que le point 1) ne devant se répéter qu'une seule fois dés lors que le code trouve une condition FALSE.

In fine, un contrôle des 28 lignes en lien avec le point 2, mais avec une seule action finale : Envoi mail ou blocage MsgBox

En vous présentant mes excuses pour mon absence de clarté, et en espérant que ces lignes vous aide à mieux comprendre ma recherche.

Bonjour,

Ah je me disais bien que quelque chose m'échappait… Je me demandais pourquoi envoyer 10x le meme mail, maintenant tout prend sens !

Ci-après la macro adaptée, en reprenant les conseils que j'évoquais plus haut. Si vous avez des questions n'hésitez pas.

Le principe est expliqué dans les commentaires du code.

Sub Vérification_Données()

  Dim derniereLigne As Long
  derniereLigne = 28
  Dim numeroLigne As Long

  With ThisWorkbook.Worksheets("Saisie")         ' pour utiliser ".Range" apres
    For numeroLigne = 9 To derniereLigne
      If .Range("E" & numeroLigne).Value = "E" _
         And IsEmpty(.Range("H" & numeroLigne)) Then
        ' probleme : la ligne contient "E" ET il manque l'info en H :
        ' on quitte la boucle et on va afficher un msg alerte
        Exit For
      End If
    Next numeroLigne
  End With

  ' on vérifie si toutes les lignes ont passé le test
  ' comment ?
  ' si numeroLigne = derniere ligne, alors
  '   on n'a pas quitté la boucle avant la fin, toutes les lignes sont correctes
  ' sinon,
  '   on a quitté la boucle avant la fin, numeroLigne < derniereLigne
  If numeroLigne < derniereLigne Then
    MsgBox "un E doit obligatoirement faire l'objet d'un H", vbExclamation
    ' sélection de la cellule incomplète
    With ThisWorkbook.Worksheets("Saisie")
      .Activate
      .Range("H" & numeroLigne).Activate
    End With
  Else
    ' sinon on est tout bon, on peut envoyer le mail
    envoi_mail
  End If
End Sub

Extra. Cela fonctionne à la perfection.

Un considérable merci pour votre aide.

Bonjour,

En consultant votre post, je vois qu'il y a une petite erreur au niveau du traitement en sortie de boucle.

Lorsqu'une boucle For/Next se termine normalement (sans interruption), le compteur est égale à la borne fin +1.

Dans le cas présent, si la dernière ligne (ligne 28) est en anomalie, elle n'est pas signalée.

Il suffit de modifier le test

If numeroLigne < derniereLigne Then en If numeroLigne - 1 < derniereLigne Then

Bonne journée

Effectivement, grave erreur de ma part ! Merci pour le retour, à corriger absolument !

Rechercher des sujets similaires à "vba probleme boucle repetition resultats"