Boucle For Each avec imbrication de Si

Bonjour à tous !

Je vous explique le contexte du fichier : j'ai deux feuilles où se trouvent différentes matières premières à commander. Pour chaque matière, je peux avoir un ou plusieurs fournisseurs et pour chaque fournisseurs, j'ai deux lignes : une pour la quantité à commander et une ou je saisis la quantité reçue.

J'ai créé une macro qui me permet de vérifier que j'ai bien reçu tout ce qui a été commandé. Pour ça, j'ai fait un userform qui me demande le jour de réception à vérifier. Le code repose sur le principe suivant : il va chercher toutes les cellules de la colonne C qui contiennent le mot "cdé" et pour chacune de ces cellules, si la cellule correspondante du jour choisi avec la quantité commandée est pleine ET que la cellule du dessous est vide, ALORS j'affiche un message comme quoi les réceptions sont incomplètes.

Lorsque je lance la macro, elle s'exécute et fonctionne met finit par me mettre un message d'erreur d'exécution 13 incompatibilité de type sur la ligne : If c.Value = "cdé" Then

Je précise que je n'ai codé que pour la première feuille CAT1, mais la macro doit vérifier également la deuxième feuille.

Je joint le fichier pour que tout ça soit plus clair !

Merci d'avance,

Eloïse

10appro.xlsm (92.23 Ko)

Bonjour Eloise,

En C32, il y a une erreur dans la recherche et donc #N/A, ce qui déclenche une erreur dans VBA
Pour contourner ce problème

  For Each c In Worksheets("CAT1").Range("C4:C200")
    If IsError(c.Value) Then GoTo SuiteC
    If c.Value = "cdé" Then
      i = c.Row
      If Cells(i, Colonne) <> "" And Cells(i + 1, Colonne) = "" Then
        MsgBox ("Attention ! Réceptions incomplètes.")
      End If
    End If
SuiteC:
  Next

A+

Rapide et efficace, j'adore ! Cela marche parfaitement !

Passons maintenant à mon deuxième problème : j'ai fait un copié-collé de ma boucle for en changeant le nom de la feuille pour répéter l'opération sur CAT2 sauf que j'avais un problème sur SuiteC: "Erreur de compilation, déclaration existante dans la portée en cours"

For Each c In Worksheets("CAT2").Range("C4:C200")
        If IsError(c.Value) Then GoTo SuiteC
        If c.Value = "cdé" Then
        i = c.Row
            If Cells(i, Colonne) <> "" And Cells(i + 1, Colonne) = "" Then
            MsgBox ("Attention ! Réceptions incomplètes.")
            End If
        End If
SuiteC:
    Next

J'ai changé le nom de SuiteC par SuiteC2 (j'ai tenté, je ne sais pas si j'ai bien fait ou pas !) :

For Each c In Worksheets("CAT2").Range("C4:C200")
        If IsError(c.Value) Then GoTo SuiteC2
        If c.Value = "cdé" Then
        i = c.Row
            If Cells(i, Colonne) <> "" And Cells(i + 1, Colonne) = "" Then
            MsgBox ("Attention ! Réceptions incomplètes.")
            End If
        End If
SuiteC2:
    Next

Maintenant, quand je lance la macro en choissant Mardi (réceptions ok sur CAT1 mais pas sur CAT2), je n'ai plus de message d'erreur par rapport à SuiteC (peut-être un bon signe ?), mais je n'ai pas la MsgBox qui s'affiche alors que sur CAT2 mes réceptions ne sont pas rentrées.

Que faire ?

Eloïse

9appro.xlsm (92.88 Ko)

Re,

Vous pouvez n'avoir qu'une seule procédure pour chaque feuille

Private Sub CommandButton1_Click()
  Dim Cel As Range
  Dim dLig As Long, Lig As Long
  Dim Colonne As Byte

  If OptionButton1 Then Colonne = 4
  If OptionButton2 Then Colonne = 5
  If OptionButton3 Then Colonne = 6
  If OptionButton3 Then Colonne = 7
  If OptionButton3 Then Colonne = 8
  If OptionButton3 Then Colonne = 9

  'Worksheets("CAT1").Activate
  With ActiveSheet
    ' Dernière ligne de la colonne C de la feuille
    dLig = .Range("C" & Rows.Count).End(xlUp).Row
    ' Pour chaque cellule
    For Each Cel In .Range("C4:C" & dLig)
      If IsError(Cel.Value) Then GoTo SuiteCel
      If Cel.Value = "cdé" Then
        Lig = Cel.Row
        If .Cells(Lig, Colonne) <> "" And .Cells(Lig + 1, Colonne) = "" Then
          MsgBox ("Attention ! Réceptions incomplètes.")
        End If
      End If
SuiteCel:
    Next
  End With
  Unload Me
End Sub

Voici le fichier

4eloisep-appro.xlsm (97.45 Ko)

A+

J'ai quand même réfléchi 2 minutes, parce que dans mon exemple je n'ai que deux feuille, mais en réalité je dois vérifier les réceptions sur une dizaine de feuille.

Voilà ce que j'ai fait pour arriver à quelque chose qui fonctionne : j'ai défini une autre variable Cel1 pour qu'après ma première boucle for, je définisse Cel = Cel1. Ainsi, je répète mon code pour la deuxième feuille de mon fichier et pour la gestion d'erreur j'utilise SuiteCel1.

Private Sub CommandButton1_Click()
  Dim Cel As Range
  Dim Cel1 As Range
  Dim dLig As Long, Lig As Long
  Dim Colonne As Byte

  If OptionButton1 Then Colonne = 4
  If OptionButton2 Then Colonne = 5
  If OptionButton3 Then Colonne = 6
  If OptionButton3 Then Colonne = 7
  If OptionButton3 Then Colonne = 8
  If OptionButton3 Then Colonne = 9

  'Worksheets("CAT1").Activate
  With Sheets("CAT1")
    ' Dernière ligne de la colonne C de la feuille
    dLig = .Range("C" & Rows.Count).End(xlUp).Row
    ' Pour chaque cellule
    For Each Cel In .Range("C4:C" & dLig)
      If IsError(Cel.Value) Then GoTo SuiteCel
      If Cel.Value = "cdé" Then
        Lig = Cel.Row
        If .Cells(Lig, Colonne) <> "" And .Cells(Lig + 1, Colonne) = "" Then
          MsgBox ("Attention ! Réception incomplète.")
        End If
      End If
SuiteCel:
    Next
  End With

  Set Cel = Cel1
  'Worksheets("CAT2").Activate
  With Sheets("CAT2")
    ' Dernière ligne de la colonne C de la feuille
    dLig = .Range("C" & Rows.Count).End(xlUp).Row
    ' Pour chaque cellule
    For Each Cel1 In .Range("C4:C" & dLig)
      If IsError(Cel1.Value) Then GoTo SuiteCel1
      If Cel1.Value = "cdé" Then
        Lig = Cel1.Row
        If .Cells(Lig, Colonne) <> "" And .Cells(Lig + 1, Colonne) = "" Then
          MsgBox ("Attention ! Réception incomplète.")
        End If
      End If
SuiteCel1:
    Next
  End With
  Unload Me
End Sub

Cela à l'air de fonctionner, je pense que je vais m'en contenter.

Merci beaucoup pour ton aide,

Bonne soirée,

Eloïse

Re,

Eloise, si vous avez un certains nombre de feuilles à vérifier en même temps, mieux vaut utiliser une boucle pour ça

Cela vous évitera de multiplier votre code par X

Private Sub CommandButton1_Click()
  Dim Ws As Worksheet
  Dim Cel As Range
  Dim dLig As Long, Lig As Long
  Dim Colonne As Byte

  If OptionButton1 Then Colonne = 4
  If OptionButton2 Then Colonne = 5
  If OptionButton3 Then Colonne = 6
  If OptionButton3 Then Colonne = 7
  If OptionButton3 Then Colonne = 8
  If OptionButton3 Then Colonne = 9

  'Worksheets("CAT1").Activate
  For Each Ws In ThisWorkbook.Worksheets
    ' Dernière ligne de la colonne C de la feuille
    dLig = Ws.Range("C" & Rows.Count).End(xlUp).Row
    ' Pour chaque cellule
    For Each Cel In Ws.Range("C4:C" & dLig)
      If IsError(Cel.Value) Then GoTo SuiteCel
      If Cel.Value = "cdé" Then
        Lig = Cel.Row
        If Ws.Cells(Lig, Colonne) <> "" And Ws.Cells(Lig + 1, Colonne) = "" Then
          MsgBox ("Attention ! Réceptions incomplètes.")
          ' Peut-être s'arréter et se positionner ou est l'erreur
          Ws.Activate: Cel.Select: Exit For
        End If
      End If
SuiteCel:
    Next Cel
  Next Ws
  Unload Me
End Sub

A+

Oui en effet je vais essayer, merci du conseil !

Bonne soirée !

Re,

Code donné post précédent

Rechercher des sujets similaires à "boucle each imbrication"