Bonjour,

Je ne connais pas bien la rubrique "Contribuez" sur le forum, mais je tente ... J'ai remarqué qu'une question (cf. plus bas) était très souvent posée sur le forum. Je me suis dit que ce serait donc intéressant d'écrire une petite explication par rapport à cette question. N'hésitez pas à me dire si la démarche n'est pas tout à fait correcte


Sur le forum VBA, il y a souvent la question/l'étonnement suivant :
J'ai fait une boucle dans laquelle je supprime des lignes selon un critère, mais toutes les lignes répondant au critère ne sont pas supprimées.
Bien souvent, il est plus efficace de passer par les filtres automatiques pour faire ce type d'opération, mais dans la première partie de cet exposé, je vais d'abord expliquer pourquoi le problème soulevé ci-dessus apparaît.
NB.: l'explication vaut pour la suppression de lignes, mais elle est aussi vraie pour l'insertion de lignes.

1. Suppression de lignes avec une boucle.
Supposons que nous voulions supprimer les lignes contenant A de la liste suivante :
Nom : list debut.png
Affichages : 14113
Taille : 1,5 Ko
Une personne faisant la remarque citée au début aura fait le code suivant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
Dim i As Long
For i = 1 To 6
    If Range("A" & i).Value = "A" Then Rows(i).Delete
Next i
Suivons pas à pas ce que fait ce code :
  1. i = 1, on vérifie si A1 vaut A --> non : on ne fait rien.
  2. i = 2, on vérifie si A2 vaut A --> oui : on supprime la ligne. La liste devient :
    Nom : liste apres.png
Affichages : 15353
Taille : 1,5 Ko
  3. i = 3, on vérifie si A3 vaut A --> non : on ne fait rien.

Et là, c'est le drame ! On a sauté un "A". Pourquoi ? Parce qu'en supprimant une ligne, on a décalé toutes les lignes en dessous vers le haut. Ainsi, la ligne 3 se trouve en ligne 2 etc ... Mais l'itération de la boucle For continue : on passe bien de i = 2 à i = 3.
Pour éviter ce problème, il faut faire la boucle en sens inverse :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
Dim i As Long
For i = 6 To 1 Step -1
    If Range("A" & i).Value = "A" Then Rows(i).Delete
Next i
Suivons pas à pas ce que fait ce code :
  1. i = 6, on vérifie si A6 vaut A --> non : on ne fait rien.
  2. i = 5, on vérifie si A5 vaut A --> non : on ne fait rien.
  3. i = 4, on vérifie si A4 vaut A --> non : on ne fait rien.
  4. i = 3, on vérifie si A3 vaut A --> oui : on supprime la ligne. La liste devient :
    Nom : liste apres.png
Affichages : 15353
Taille : 1,5 Ko
  5. i = 2, on vérifie si A2 vaut A --> oui : on supprime la ligne.
  6. i = 1, on vérifie si A1 vaut A --> non : on ne fait rien

Et vous voyez qu'on a bien visité toutes les cellules de la colonne A.

2. Suppression de ligne avec le filtre automatique (à partir d'XL2007)
Intuitivement, on effectue une boucle pour supprimer des lignes selon un critère. Mais avec Excel-VBA, il existe une méthode plus rapide et efficace : très intéressant s'il y a beaucoup de lignes à vérifier ! Pour cela, on peut utiliser les filtres automatiques. Avec l'enregistreur de macro, on retrouve rapidement la façon de les utiliser en VBA : Range.AutoFilter.
Voici ce que nous allons faire :
  1. Filtrer sur la valeur à éliminer
  2. Supprimer les lignes restantes (donc celles qui contiennent la valeur à éliminer)
  3. Enlever le filtre pour ne voir que les valeurs non éliminées.

Avant d'effectuer cela, on ajoute un en-tête à nos données :
Nom : entete.png
Affichages : 14057
Taille : 1,9 Ko
Puis, on utilise AutoFilter :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
Range("A1:A7").AutoFilter Field:=1, Criteria1:="A"
Ceci va filtrer notre liste pour ne garder que les "A".
Ensuite, il ne reste plus qu'à supprimer ces lignes :
Et enfin, on n'oublie pas d'enlever le filtre (car maintenant, il n'y a plus de "A", donc si on filtre sur "A", on ne verra plus rien ...) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
Range("A1:A7").AutoFilter Field:=1
Bien sûr, il est possible de filtrer sur plusieurs critères et sur plusieurs colonnes avant de supprimer les lignes. Tout ceci se découvre facilement avec l'enregistreur de macro.

J'espère que ce petit message vous aura aidé à comprendre comment supprimer des lignes selon un critère.
A bientôt sur le forum !