🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA supprimer des lignes dans Excel — lignes, lignes vides et lignes selon une condition (bouclez à rebours !)

|

VBA supprimer des lignes dans Excel — lignes, lignes vides et lignes selon une condition (bouclez à rebours !)

En bref — Supprimer une ligne est une modification structurelle : elle ne vide pas la ligne, elle la retire et fait remonter d'un cran toutes les lignes du dessous. Ce simple fait est à l'origine du bug VBA le plus courant qui soit — une boucle vers le bas qui supprime des lignes saute chaque ligne qui suivait une ligne supprimée, parce que les numéros de ligne se décalent sous la boucle. Le correctif tient en un mot : bouclez à rebours (For i = last To first Step -1). Supprimez la ligne entière avec .EntireRow.Delete, et pour de nombreuses lignes éparpillées, réunissez-les dans un seul Union et supprimez une seule fois — c'est plus rapide et cela contourne complètement le problème de décalage.

' Supprimer chaque ligne dont la colonne A est vide - boucler de BAS en HAUT.
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Data")
Dim lastRow As Long, i As Long
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

For i = lastRow To 2 Step -1                 ' <-- à rebours, sinon vous sautez des lignes
    If Trim(ws.Cells(i, "A").Value) = "" Then ws.Rows(i).EntireRow.Delete
Next i

« Supprimez ces lignes » ressemble à la tâche la plus simple de l'automatisation Excel, et c'est celle qui piège presque tout le monde du premier coup. La raison n'est pas la méthode Delete — c'est que supprimer modifie précisément ce sur quoi vous bouclez. Prenez le bon sens de parcours et la suppression par condition devient triviale ; prenez le mauvais et votre macro laisse silencieusement la moitié des lignes concernées en place. Ce guide est bâti autour de cette seule idée, puis des schémas pratiques qui en découlent.

Ce que vous allez apprendre

  • Le modèle mental — supprimer retire une ligne et fait remonter tout ce qui est en dessous
  • La règle la plus importante — bouclez à rebours, sinon une boucle vers le bas saute des lignes
  • Pourquoi .EntireRow.Delete est la cible sûre, et ce que fait .Delete sur une cellule à la place
  • Le schéma plus rapide pour les lignes éparpillées — construire un Union, supprimer une seule fois
  • Retirer les lignes vides et supprimer par condition sans casser les formules de référence

Le modèle mental : une suppression déplace la grille, elle ne vide pas une ligne

Deux opérations totalement différentes portent le même nom de « suppression ». Appuyer sur Suppr efface une cellule — la ligne reste, la valeur disparaît. Un clic droit ▸ Supprimer, ou Rows(i).Delete dans le code, retire la ligne — la ligne cesse d'exister et chaque ligne située en dessous remonte d'un cran pour combler le trou. La ligne qui était la 11 devient la 10.

Ce comblement du trou, c'est toute l'histoire. Quand vous supprimez la ligne 10, les données de la ligne 11 se retrouvent dans la ligne 10. Tout code qui supposait que « la ligne 11 contient toujours ce qu'elle contenait il y a un instant » est désormais faux. C'est pourquoi supprimer des lignes n'a rien à voir avec les autres boucles que vous écrivez : l'adresse des données que vous n'avez pas encore traitées change à l'instant même où vous supprimez. Vous modifiez le système de coordonnées pendant que vous le parcourez.

Gardez cette image en tête — sous la ligne supprimée, tout remonte — et chaque règle qui suit n'en est qu'une conséquence.

La règle la plus importante : bouclez à rebours, sinon vous sautez des lignes

Voici le bug, écrit comme presque tout le monde l'écrit la première fois :

' FAUX - une boucle vers le bas sur des lignes que vous supprimez.
For i = 2 To lastRow
    If ws.Cells(i, "A").Value = "DELETE" Then ws.Rows(i).EntireRow.Delete
Next i

Supposons que les lignes 5 et 6 contiennent toutes deux "DELETE". La boucle atteint i = 5, supprime la ligne 5, et la ligne 6 remonte pour devenir la nouvelle ligne 5. Mais la boucle passe alors à i = 6 — soit la ligne qui était la ligne 7. L'ancienne ligne 6 n'a jamais été vérifiée. Deux correspondances voisines, et la seconde survit. Sur un bloc de correspondances, vous en laissez à peu près une sur deux, et le symptôme (« certaines lignes n'ont pas été supprimées ») paraît aléatoire.

Le correctif ne coûte rien. Parcourez de bas en haut :

' CORRECT - supprimer de la dernière ligne jusqu'à la première.
For i = lastRow To 2 Step -1
    If ws.Cells(i, "A").Value = "DELETE" Then ws.Rows(i).EntireRow.Delete
Next i

En sens inverse, supprimer la ligne 6 fait remonter les lignes situées sous la 6 — mais vous les avez déjà traitées. Les lignes que vous n'avez pas encore examinées sont toutes au-dessus de celle que vous venez de supprimer, et leurs numéros n'ont pas bougé. Le décalage a toujours lieu ; simplement, il se produit derrière vous, là où il ne peut faire aucun dégât. Dès qu'une boucle supprime des lignes, elle utilise Step -1. Retenez cela et la moitié des bugs de suppression disparaît.

La règle qui garde les données alignées : supprimez la ligne, pas une cellule

Delete s'applique à n'importe quelle plage, et plus la plage est petite, plus elle est dangereuse. Si vous écrivez ws.Cells(i, "A").Delete, vous supprimez une seule cellule, et Excel fait remonter les cellules situées en dessous, dans la seule colonne A — en laissant les colonnes B, C et D exactement où elles étaient. À partir de là, chaque ligne est désalignée : la colonne A affiche un enregistrement tandis que B et C affichent celui du dessous. Aucune erreur ne se déclenche ; vos données sont simplement mélangées en silence.

Supprimer la ligne entière garde chaque colonne alignée :

ws.Rows(i).EntireRow.Delete        ' toute la ligne 11 disparaît ; 12, 13... remontent ensemble
ws.Cells(i, "A").EntireRow.Delete  ' identique - .EntireRow promeut une cellule en sa ligne entière

.EntireRow est la promotion de « cette cellule » vers « la ligne entière dans laquelle elle se trouve », et c'est presque toujours ce que vous voulez. Réservez le Range.Delete nu avec Shift:=xlUp/xlToLeft au cas rare où vous voulez réellement déplacer un bloc de cellules, et non retirer un enregistrement.

Le schéma plus rapide et plus sûr : réunir un Union et supprimer une seule fois

Boucler et supprimer ligne par ligne fonctionne dès lors que vous bouclez à rebours, mais sur de grandes feuilles c'est lent — chaque .Delete force Excel à décaler la grille et à recalculer. Il existe un schéma à la fois plus rapide et insensible au piège du décalage, parce qu'il effectue toute la suppression en une seule étape : constituez avec Union une Range regroupant chaque ligne à retirer, puis supprimez le tout à la fin.

Dim victims As Range, i As Long
For i = 2 To lastRow                          ' le sens n'importe pas - on supprime plus tard
    If ws.Cells(i, "A").Value = "DELETE" Then
        If victims Is Nothing Then
            Set victims = ws.Rows(i)
        Else
            Set victims = Union(victims, ws.Rows(i))
        End If
    End If
Next i

If Not victims Is Nothing Then victims.EntireRow.Delete   ' une seule suppression, toutes les lignes d'un coup

Comme aucune ligne n'est retirée avant la fin de la boucle, les numéros de ligne ne bougent jamais pendant le parcours — une boucle vers le bas est donc parfaitement sûre ici. Et une unique .Delete sur une plage à zones multiples est spectaculairement plus rapide que des centaines de suppressions individuelles. Ma règle empirique : quelques lignes, bouclez à rebours ; des centaines ou des milliers, réunissez un Union (ou filtrez — voir plus bas) et supprimez une seule fois. Enveloppez l'une ou l'autre dans Application.ScreenUpdating = False / Calculation = xlManual et les grosses suppressions passent de quelques secondes à instantanées.

Lignes vides, conditions et le piège des références

Supprimer les lignes vides dispose d'un raccourci d'une ligne qui bat n'importe quelle boucle — laissez Excel trouver les vides :

On Error Resume Next   ' SpecialCells lève l'erreur 1004 s'il n'y a aucun vide
ws.Range("A2:A" & lastRow).SpecialCells(xlCellTypeBlanks).EntireRow.Delete
On Error GoTo 0

SpecialCells(xlCellTypeBlanks) renvoie chaque cellule vide de la colonne A sous forme d'une plage à zones multiples, et .EntireRow.Delete en supprime toutes les lignes d'un seul coup. Deux réserves : elle se fonde sur une seule colonne (une ligne dont A est vide mais B rempli disparaît quand même), et elle lève une erreur en l'absence de vide — d'où le garde-fou On Error.

Pour supprimer par condition sur de gros volumes, le geste de pro est l'AutoFilter : filtrez les lignes dont vous ne voulez pas, supprimez celles qui restent visibles, retirez le filtre. C'est l'approche la plus rapide de toutes, car c'est Excel qui fait la correspondance :

With ws.Range("A1").CurrentRegion
    .AutoFilter Field:=1, Criteria1:="DELETE"
    .Offset(1).SpecialCells(xlCellTypeVisible).EntireRow.Delete  ' ignorer la ligne d'en-tête
End With
ws.AutoFilterMode = False

Un piège leur survit à tous : supprimer des lignes décale les références. Si une formule ailleurs pointe vers =A20 et que vous supprimez la ligne 5, Excel la réécrit en =A19 — en général ce que vous voulez. Mais si vous supprimez la ligne dont dépend une formule, celle-ci se transforme en #REF!. Supprimer des lignes sous des formules actives est la cause classique d'une feuille pleine d'erreurs #REF! : avant une suppression en masse, sachez si quoi que ce soit en aval référence les lignes que vous retirez. Trouver où s'arrêtent vos données est une compétence connexe — voir VBA Last Row.

Comment ExcelMaster aide

Le code de suppression de lignes a plusieurs façons discrètes de mal tourner : la boucle vers le bas qui saute des lignes, la suppression d'une seule cellule qui désaligne les colonnes, l'appel à SpecialCells qui plante en l'absence de vide, la suppression en masse qui laisse des #REF! derrière elle. Aucune ne déclenche d'erreur visible — elles produisent simplement des données légèrement fausses.

ExcelMaster vous laisse plutôt décrire le résultat. Dites « supprime chaque ligne dont la colonne A est vide » ou « retire les lignes dont le statut est Annulé », et il écrit la boucle dans le bon sens (ou un Union/filtre pour de gros volumes), cible .EntireRow, protège les cas limites et sauvegarde d'abord la feuille. Vous gardez le classeur et le code ; vous vous épargnez le moment où un Step -1 oublié corrompt silencieusement un rapport.

Questions fréquentes

Pourquoi ma boucle VBA saute-t-elle des lignes lors d'une suppression ?

Parce que supprimer une ligne fait remonter d'un cran chaque ligne du dessous, alors qu'une boucle vers le bas continue de s'incrémenter. Après la suppression de la ligne 5, l'ancienne ligne 6 devient la ligne 5 — et la boucle passe à la ligne 6, qu'elle saute. Bouclez plutôt à rebours : For i = lastRow To 2 Step -1. Les lignes non encore vérifiées sont alors toujours au-dessus de la suppression, si bien que leurs numéros ne bougent jamais.

Comment supprimer une ligne entière en VBA ?

Utilisez .EntireRow.Delete — par exemple ws.Rows(11).EntireRow.Delete ou ws.Cells(11, "A").EntireRow.Delete. Les deux retirent la ligne entière, de sorte que chaque colonne reste alignée. Évitez Cells(11, "A").Delete, qui supprime une seule cellule et ne décale que cette colonne, mélangeant tout le reste.

Quelle est la façon la plus rapide de supprimer de nombreuses lignes en VBA ?

Pour des centaines ou des milliers de lignes, ne supprimez pas une par une. Soit vous appliquez un AutoFilter aux lignes à éliminer et supprimez les cellules visibles en une étape, soit vous constituez un Union de toutes les lignes ciblées pendant la boucle et appelez .EntireRow.Delete une seule fois à la fin. Une unique suppression multi-lignes est bien plus rapide que de nombreuses suppressions individuelles, surtout avec ScreenUpdating et Calculation désactivés.

Comment supprimer toutes les lignes vides en VBA ?

ws.Range("A2:A" & lastRow).SpecialCells(xlCellTypeBlanks).EntireRow.Delete retire en une seule opération chaque ligne dont la colonne A est vide. Enveloppez-la dans On Error Resume Next / On Error GoTo 0, car SpecialCells lève une erreur lorsqu'il n'y a aucune cellule vide à trouver.

Pourquoi ai-je des erreurs #REF! après avoir supprimé des lignes ?

Supprimer des lignes décale les références de cellule. Les formules qui pointent au-delà des lignes supprimées sont renumérotées automatiquement, mais toute formule qui référençait une cellule à l'intérieur d'une ligne supprimée ne peut plus se résoudre et devient #REF!. Avant une suppression en masse, vérifiez si d'autres cellules dépendent des lignes que vous vous apprêtez à retirer.

Testé dans

Testé dans : Excel 365 (Windows 11), VBA 7.1 — dernière vérification le 07/08/2026.

Guides associés : VBA Insert Rows and Columns · VBA Hide Columns and Rows · VBA Last Row · VBA For Loop · VBA Range