Option Explicit
Sub Macro1()
Dim O As Worksheet 'déclare la variable O (Onglet)
Dim TV As Variant 'déclare la variable TV (Tableau des valeurs)
Dim D As Object 'déclare la variable D (Dictionnaire)
Dim I As Integer 'déclare la variable I (Incrément)
Dim J As Integer 'déclare la variable J (incrément)
Dim K As Integer 'déclare la variable K (incrément)
Dim TMP As Variant 'déclare la variable TMP (tableau TeMPoraire)
Dim PL As Integer 'déclare la variable PL (Première Ligne)
Dim MSG As String 'déclare la variable MSG (MeSsaGe)
Dim LAF() As Integer 'déclare la variable PAF (Ligne À Effacer)
Dim PLAF As Range 'déclare la variable PLAF (Plage des Lignes À Effacer)
Set O = Worksheets("Feuil1") 'définit l'onglet O
TV = O.Range("A1").CurrentRegion 'définit le tableau des valeurs TV
Set D = CreateObject("Scripting.Dictionary") 'définit le dictionnaire D
For I = 2 To UBound(TV, 1) 'boucle sur toutes les lignes I du tableau des valeurs TV (en partant de la seconde)
If TV(I, 13) = "" Or TV(I, 14) = "" Or TV(I, 17) = "" Then GoTo suite 'si une des 3 valeurs est vide, va à l'étiquette "suite"
If TV(I, 13) = "x" Or TV(I, 14) = "x" Or TV(I, 17) = "x" Then GoTo suite 'si une des 3 valeurs vaut "x", va à l'étiquette "suite"
If TV(I, 17) <> "attente" Then GoTo suite 'si la colonne Q est différente de "attente", va à l'étiquette "suite"
D(TV(I, 13) & TV(I, 14) & TV(I, 17)) = "" 'alimente le dictionnaire D avec les 3 valeurs concaténées
suite: 'étiquette
Next I 'prochaine ligne de la boucle
TMP = D.keys 'alimente le tableau temporaire TMP avec la liste du dictionnaire D sans doublons (les clés)
For J = 0 To UBound(TMP) 'boucle 1 : sur tous les éléments du tableau temporaire TMP
PL = 0 'initialise la première ligne PL
For I = 2 To UBound(TV, 1) 'boucle 2 sur toutes les lignes I du tableau des valeurs TV (en partant de la seconde)
If TV(I, 13) & TV(I, 14) & TV(I, 17) = TMP(J) Then 'condition 1 : si les 3 valeurs concatenées sont égales à TMP(J)
If PL <> 0 Then 'condition 2 : si la première ligne est différente de 0
K = K + 1 'incrémente K
ReDim Preserve LAF(1 To K) 'redimensionne le tableau des lignes à effacer LAF
LAF(K) = I 'récupère la ligne I de la boucle 2 dans le tableau LAF
Else 'sinon (si s'est la première ligne)
PL = I 'définit la première ligne PL
'définit le message MSG
MSG = IIf(MSG = "", "Les premières Lignes sont :" & vbCrLf & I & " - " & TV(I, 13) & " - " & TV(I, 14) & " - " & TV(I, 17), _
MSG & vbCrLf & I & " - " & TV(I, 13) & " - " & TV(I, 14) & " - " & TV(I, 17))
End If 'fin de la condition 2
End If 'fin de la condition 1
Next I 'prochaine ligne de la boucle 2
Next J 'prochain élément de la boucle 1
Set PLAF = O.Range("A1") 'initialise la plage PLAF
For I = LBound(LAF) To UBound(LAF) 'boucle sur toutes les lignes du tableau des ligne à effacer LAF
Set PLAF = IIf(PLAF.Cells.Count = 1, O.Rows(LAF(I)), Application.Union(PLAF, O.Rows(LAF(I)))) 'redéfinit la plage PLAF
Next I 'prochaine ligne de la boucle
PLAF.Select 'sélectionne la plage PLAF
MsgBox MSG & vbCrLf & "Seuls les donblons sont sélectionnés !"
End Sub