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
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:
NextA+
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:
NextJ'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:
NextMaintenant, 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
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 SubVoici le fichier
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 SubCela à 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 SubA+
Oui en effet je vais essayer, merci du conseil !
Bonne soirée !