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

VBA AutoFilter dans Excel — filtrer des lignes dans le code (et pourquoi masqué n'est pas supprimé)

|

VBA AutoFilter dans Excel — filtrer des lignes dans le code (et pourquoi masqué n'est pas supprimé)

En brefAutoFilter masque les lignes qui ne correspondent pas à vos critères — il ne les retire pas. Ces lignes masquées sont toujours dans la plage, toujours comptées par SUM, et toujours copiées par un simple .Copy. Pour lire, copier ou supprimer uniquement ce qui est visible, vous devez passer par .SpecialCells(xlCellTypeVisible). Et méfiez-vous du piège de la bascule : appeler .AutoFilter sans argument active ou désactive le filtrage, si bien qu'une macro qui « pose un filtre » peut le retirer à sa deuxième exécution. Nettoyez d'abord l'état avec .AutoFilterMode = False.

' Filtrer un tableau sur Region = "West", puis agir sur les lignes VISIBLES seulement.
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Sales")
ws.AutoFilterMode = False                      ' nettoyer d'abord tout filtre residuel

With ws.Range("A1").CurrentRegion              ' tout le tableau, en-tete compris
    .AutoFilter Field:=2, Criteria1:="West"    ' Field est compte a partir de 1 DANS la plage
    ' lignes de donnees visibles seulement (ignorer l'en-tete avec Offset(1)) :
    .Offset(1).SpecialCells(xlCellTypeVisible).EntireRow.Copy _
        Destination:=Worksheets("West").Range("A1")
End With
ws.AutoFilterMode = False                       ' retirer le filtre une fois termine

AutoFilter est le moyen le plus rapide de restreindre un tableau aux lignes qui vous intéressent, et c'est le moteur derrière la suppression en masse la plus rapide de tout le VBA Excel. Mais il trompe son monde, parce qu'il a l'air d'avoir retiré des lignes alors qu'il n'a fait que les masquer. Presque tous les bugs d'AutoFilter sont une variante de ce seul malentendu, et c'est donc là que commence ce guide.

Ce que vous allez apprendre

  • Le modèle mental — AutoFilter est une vue, pas une suppression ; les lignes masquées sont toujours là
  • Pourquoi SUM et .Copy incluent encore les lignes filtrées, et comment SpecialCells(xlCellTypeVisible) y remédie
  • Définir des critères — valeurs simples, opérateurs de comparaison, deux conditions, et « dans une liste »
  • Le piège de la bascule — pourquoi un appel .AutoFilter sans argument désactive le filtrage
  • Le schéma pro filtrer-puis-supprimer pour retirer des milliers de lignes rapidement
  • AutoFilter vs la fonction FILTER vs le filtre avancé — lequel choisir

Le modèle mental : un filtre est une vue, pas une suppression

Quand vous appliquez un filtre, Excel fait exactement une chose : il met la propriété hidden sur chaque ligne qui ne correspond pas. Les données ne bougent pas. Rien n'est retiré. Vous regardez la même plage à travers un pochoir qui masque certaines lignes.

C'est toute l'idée, et elle a une conséquence qui surprend la première fois : tout ce qui opère sur la plage voit encore les lignes masquées. =SUM(B2:B1000) additionne les nombres filtrés. Range("B2:B1000").Copy les copie tous, masqués ou non. Une boucle For Each cell les visite tous. Le filtre a changé ce que vous voyez ; il n'a pas changé ce que la plage contient.

Le modèle mental est donc une question à se poser avant chaque opération sur un tableau filtré : est-ce que je veux toutes les lignes, ou seulement les visibles ? Si la réponse est « seulement les visibles », vous ne pouvez pas utiliser la plage directement — vous devez demander explicitement à Excel le sous-ensemble visible. C'est l'unique habitude qui rend AutoFilter fiable.

La règle la plus importante : atteignez les lignes visibles via SpecialCells

Pour ne toucher qu'aux lignes que le filtre laisse apparentes, vous convertissez la plage en ses cellules visibles :

Dim visible As Range
On Error Resume Next     ' xlCellTypeVisible leve une error 1004 si rien n'est visible
Set visible = ws.Range("A1").CurrentRegion.Offset(1) _
                  .SpecialCells(xlCellTypeVisible)
On Error GoTo 0

If Not visible Is Nothing Then
    ' visible est une plage MULTI-ZONES - les lignes filtrees ne sont pas contigues
    MsgBox "Visible rows: " & visible.Rows.Count
End If

Deux choses à intégrer ici. Premièrement, SpecialCells(xlCellTypeVisible) renvoie une plage à zones multiples — car les lignes visibles sont éparpillées, avec des lignes masquées entre elles. Parcourez-la avec For Each area In visible.Areas quand vous devez traiter des blocs, ou utilisez des opérations .EntireRow qui gèrent les zones pour vous. Deuxièmement, elle lève une error 1004 quand rien n'est visible (un filtre qui n'a trouvé aucune ligne), alors protégez-la avec On Error. Sautez SpecialCells et opérez sur la plage brute, et vous travaillez en silence sur les lignes masquées aussi — l'erreur d'AutoFilter la plus courante qui soit.

Définir des critères : valeurs, opérateurs et listes

AutoFilter prend un Field (compté à partir de 1 dans la plage filtrée, pas la lettre de colonne de la feuille) et un ou deux critères :

With ws.Range("A1").CurrentRegion
    ' valeur exacte
    .AutoFilter Field:=2, Criteria1:="West"

    ' comparaison - l'operateur est dans la chaine
    .AutoFilter Field:=3, Criteria1:=">1000"

    ' deux conditions sur un meme champ (entre 100 et 500)
    .AutoFilter Field:=3, Criteria1:=">=100", Operator:=xlAnd, Criteria2:="<=500"

    ' "dans une liste" - un tableau Array plus xlFilterValues
    .AutoFilter Field:=2, Criteria1:=Array("West", "East"), Operator:=xlFilterValues
End With

Le piège qui attrape tout le monde une fois : Field se compte depuis le bord gauche de la plage sur laquelle vous avez appelé .AutoFilter, pas depuis la colonne A de la feuille. Si votre tableau commence en colonne C, Field:=1 est la colonne C. Trompez-vous sur ce décalage et vous filtrez la mauvaise colonne, sans la moindre erreur.

Le piège de la bascule : un AutoFilter nu désactive le filtrage

.AutoFilter appelé sans argument est une bascule — il active les flèches de filtre si elles sont désactivées, et les désactive si elles sont actives. Cela le rend dangereux dans une macro susceptible de s'exécuter plus d'une fois :

ws.Range("A1").CurrentRegion.AutoFilter    ' une fois : fleches ON. encore une fois : fleches OFF.

Cette même dépendance à l'état frappe de façon plus subtile : un filtre laissé par une exécution précédente — ou par un utilisateur qui a filtré à la main — change en silence le sens de « visible » la prochaine fois que votre code lit la plage. Ne faites pas confiance à l'état de filtre hérité. Commencez par le nettoyer, et nettoyez-le de nouveau à la fin :

ws.AutoFilterMode = False   ' retirer tout filtre existant - repartir de zero
' ... appliquer votre filtre, faire votre travail ...
ws.AutoFilterMode = False   ' laisser la feuille telle que vous l'avez trouvee

Tester If ws.AutoFilterMode Then vous dit si un filtre est actuellement actif. Rendre votre macro indépendante de l'état — nettoyer, filtrer, travailler, nettoyer — voilà ce qui met fin à la catégorie de bugs « a marché une fois, cassé la deuxième ».

Le schéma à mémoriser : filtrer, puis supprimer les lignes visibles

C'est pour cela qu'AutoFilter mérite sa place dans du code sérieux. Pour supprimer des milliers de lignes correspondant à une condition, filtrer puis supprimer les cellules visibles est spectaculairement plus rapide que de boucler — Excel fait la correspondance, et un seul .Delete les retire toutes :

With ws.Range("A1").CurrentRegion
    .AutoFilter Field:=5, Criteria1:="Cancelled"
    ' supprimer les lignes de donnees visibles - Offset(1) ignore l'en-tete, sinon vous supprimez vos titres
    On Error Resume Next
    .Offset(1).SpecialCells(xlCellTypeVisible).EntireRow.Delete
    On Error GoTo 0
End With
ws.AutoFilterMode = False

Le .Offset(1) est le piège : sans lui, la ligne d'en-tête est visible elle aussi et se fait supprimer avec les données. Cette approche filtrer-puis-supprimer s'accorde naturellement avec les techniques de suppression de VBA Delete Rows — et c'est celle que je préfère à une boucle à rebours dès que le nombre de correspondances est grand.

AutoFilter vs fonction FILTER vs filtre avancé

Trois outils partagent le mot « filtre » et résolvent des problèmes différents :

  • AutoFilter masque les lignes non correspondantes sur place. À utiliser quand vous voulez voir, copier ou supprimer un sous-ensemble d'un tableau existant. C'est une vue sur l'original.
  • La fonction de feuille FILTER() déverse un nouveau tableau de lignes correspondantes ailleurs, vivant et recalculé. À utiliser quand vous voulez une liste pilotée par formule qui se met à jour toute seule — sans macro.
  • Le filtre avancé (Range.AdvancedFilter) peut copier les correspondances vers un autre emplacement ou extraire des valeurs uniques à l'aide d'une plage de critères. À utiliser pour des extractions complexes, multi-conditions.

Le jugement : pour « restreindre ce tableau afin d'agir sur les correspondances », AutoFilter est le bon choix. Si vous vous surprenez à vouloir une liste vivante et auto-actualisée des correspondances ailleurs, arrêtez d'écrire une macro — c'est le travail de la fonction FILTER(), pas d'AutoFilter.

Comment ExcelMaster aide

Les pièges d'AutoFilter sont tous silencieux : sommer une plage filtrée en incluant les lignes masquées, copier et tout récupérer, supprimer sans SpecialCells et toucher les mauvaises cellules, le décalage du Field, la bascule qui désactive votre filtre à la deuxième exécution. Aucun ne déclenche d'erreur — ils agissent simplement sur des lignes que vous croyiez disparues.

ExcelMaster vous laisse dire ce que vous voulez afficher dans le tableau. Décrivez « ne garde que les lignes de la région Ouest au-dessus de 1000 » ou « supprime toutes les commandes Annulées », et il nettoie d'abord l'état de filtre périmé, obtient le bon indice de Field, passe par SpecialCells(xlCellTypeVisible) pour tout ce qui ne touche que les lignes visibles, et sauvegarde la feuille avant de supprimer. Vous gardez le classeur et le code ; vous vous épargnez le moment où une ligne masquée se glisse dans votre total.

Questions fréquentes

AutoFilter en VBA supprime-t-il les lignes qu'il filtre ?

Non. AutoFilter ne fait que masquer les lignes non correspondantes — elles restent dans la plage, toujours comptées par SUM, toujours copiées par .Copy, et toujours visitées par les boucles. Pour ne travailler que sur les lignes visibles, vous devez passer par .SpecialCells(xlCellTypeVisible). Pour réellement retirer des lignes, filtrez puis supprimez les cellules visibles.

Pourquoi SUM inclut-il encore mes lignes filtrées en VBA ?

Parce que filtrer masque les lignes, cela ne les retire pas, et SUM additionne les valeurs masquées. Utilisez SUBTOTAL(109, range) au lieu de SUM pour ne totaliser que les lignes visibles, ou en VBA sommez .SpecialCells(xlCellTypeVisible). C'est le signe le plus clair qu'un filtre est une vue, pas une suppression.

Comment filtrer selon deux conditions dans AutoFilter en VBA ?

Passez Criteria1, un Operator et Criteria2. Pour un intervalle, utilisez xlAnd (Criteria1:=">=100", Operator:=xlAnd, Criteria2:="<=500") ; pour « l'un ou l'autre », utilisez xlOr. Pour « valeur dans une liste », passez un tableau Array à Criteria1 avec Operator:=xlFilterValues.

Pourquoi mon AutoFilter se désactive-t-il quand la macro s'exécute de nouveau ?

Parce qu'appeler .AutoFilter sans argument est une bascule — il active le filtrage s'il est désactivé et le désactive s'il est actif. Exécutez-le deux fois et le filtre disparaît. Rendez la macro indépendante de l'état : appelez ws.AutoFilterMode = False pour nettoyer d'abord, puis appliquez votre filtre avec des arguments explicites.

Quelle est la façon la plus rapide de supprimer des lignes selon une condition en VBA ?

Appliquez AutoFilter pour cibler les lignes à éliminer, puis supprimez les cellules visibles en un seul appel : .Offset(1).SpecialCells(xlCellTypeVisible).EntireRow.Delete (le Offset(1) ignore l'en-tête). Excel fait la correspondance et une seule suppression les retire toutes, ce qui est bien plus rapide que de boucler ligne par ligne.

Testé dans

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

Guides associés : VBA Find · VBA Sort · VBA Delete Rows · VBA Last Row · VBA Range