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

VBA Last Row dans Excel — trouver la vraie fin de vos données (et le piège de chaque méthode)

|

VBA Last Row dans Excel — trouver la vraie fin de vos données (et le piège de chaque méthode)

TL;DR — Arrêtez de coder en dur Range("A1:A100"). Vos données grandissent et rétrécissent : trouvez donc leur bord à l'exécution. L'idiome canonique est Cells(Rows.Count, "A").End(xlUp).Row — il simule l'appui sur Ctrl+↑ depuis tout en bas de la colonne. Utilisez Rows.Count, jamais un 65536 codé en dur. Il existe quatre façons de demander « où s'arrêtent les données ? » et chacune répond à une question légèrement différente : .End(xlUp) trouve la dernière cellule non vide d'une colonne, .End(xlDown) s'arrête au premier trou, .UsedRange surestime, et .Find est la seule vraiment à l'épreuve des trous. Choisissez la mauvaise méthode et vous traitez les mauvaises lignes — sans aucune erreur pour vous prévenir.

Trouver la dernière ligne est la toute première chose qu'une macro doit faire avant de pouvoir boucler, copier, trier ou effacer. C'est aussi là que les débutants écrivent la ligne la plus fragile de toute la procédure : un A2:A500 codé en dur. Ajoutez une ligne et la macro la rate ; supprimez des lignes et elle traite des centaines de cellules vides. Le vrai VBA ne suppose jamais la taille des données — il la mesure.

Ce que vous allez apprendre

  • L'idiome canonique Cells(Rows.Count, "A").End(xlUp).Row, décodé morceau par morceau
  • Pourquoi 65536 est une mine et Rows.Count la solution
  • Le mode de défaillance caché dans chacune des quatre méthodes (.End(xlUp), .End(xlDown), .UsedRange, .Find)
  • Comment trouver la dernière colonne, pas seulement la dernière ligne
  • Quand les trous dans vos données imposent de passer de .End à .Find

Le modèle mental : vos données ont un bord, et Excel ne vous le donnera pas

Une feuille de calcul est une grille d'un million de lignes. Vos données occupent un rectangle à l'intérieur, mais Excel ne conserve pas une propriété « dernière ligne » bien rangée que vous pourriez simplement lire. Vous devez donc marcher jusqu'au bord et demander où vous avez atterri. Toute technique fiable est une variante de « partez d'un endroit dont vous savez qu'il est au-delà des données, puis sautez en arrière jusqu'à la dernière chose réellement présente ».

L'image mentale de l'idiome canonique, c'est une personne debout tout en bas d'une colonne qui appuie sur Ctrl+↑ : le curseur remonte d'un bond et s'arrête sur la dernière cellule qui contient quelque chose. C'est exactement ce que fait .End(xlUp) dans le code.

Sub FindLastRow()
    Dim ws As Worksheet
    Set ws = ActiveSheet

    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

    Debug.Print "Last row with data in column A: " & lastRow
End Sub

Lisez-le de l'intérieur vers l'extérieur : ws.Rows.Count est le nombre de lignes de la feuille (1 048 576 sur les Excel modernes). Cells(cela, "A") est la toute dernière cellule de la colonne A. .End(xlUp) remonte jusqu'à la dernière cellule non vide. .Row en lit le numéro de ligne. Cette unique ligne est le cheval de bataille — mais seulement si vous comprenez le piège qu'elle transporte.

La règle qui vous évite le pire bug de dernière ligne : ne jamais coder 65536 en dur

Pendant une décennie, les tutoriels ont écrit Cells(65536, 1).End(xlUp).Row, parce que 65 536 était la dernière ligne de l'ancien format .xls. Les feuilles .xlsx modernes comptent 1 048 576 lignes. Si vos données dépassent la ligne 65 536 et que vous démarrez votre remontée à 65 536, vous commencez au-dessus d'une partie de vos données et renvoyez silencieusement une dernière ligne trop petite — coupant votre boucle au milieu du tableau.

' FRAGILE — démarre au-dessus de toute donnée située sous la ligne 65536
lastRow = Cells(65536, 1).End(xlUp).Row

' CORRECT — démarre toujours du vrai bas de CETTE feuille
lastRow = Cells(Rows.Count, 1).End(xlUp).Row

Rows.Count lit le vrai nombre de lignes de la feuille sur laquelle le code s'exécute : il est donc à l'épreuve du futur et des versions. Il n'existe aucun cas où coder le nombre en dur serait préférable. Faites de Cells(Rows.Count, col) un réflexe.

La règle qui relie chaque méthode à son mode de défaillance

Voici la partie que tous les tutoriels sautent : les quatre méthodes courantes ne renvoient pas la même réponse, car elles répondent à des questions différentes. Apprenez le mode de défaillance de chacune et vous saurez toujours laquelle choisir.

.End(xlUp) — dernière cellule non vide d'une colonne. Le choix par défaut. Son angle mort : elle ne regarde qu'une seule colonne. Si vous choisissez une colonne présentant un trou là où se trouve la dernière ligne (disons que le nom de la ligne 500 est vide mais pas son montant), vous vous arrêtez trop tôt. Choisissez une colonne garantie remplie sur chaque ligne de données — un identifiant ou une clé — ou trouvez la dernière ligne sur tout le tableau avec .Find.

.End(xlDown) — premier trou depuis le haut. C'est Ctrl+↓ depuis la ligne

  1. Elle ne trouve pas la dernière ligne ; elle trouve la ligne juste avant la première cellule vide. Une seule cellule vide au milieu de votre colonne vous tronque au premier bloc. N'utilisez jamais .End(xlDown) pour trouver la fin des données — uniquement pour trouver le bas d'une plage ininterrompue.
' A1:A10 contient des données, A6 est vide, A7:A10 en contient d'autres
Cells(1, 1).End(xlDown).Row     ' -> 5   (arrêté au trou — FAUX pour « dernière ligne »)
Cells(Rows.Count, 1).End(xlUp).Row  ' -> 10  (vraie dernière ligne — JUSTE)

.UsedRange — la boîte englobante mise en cache par Excel. ws.UsedRange, ce ne sont pas vos données ; ce sont toutes les cellules qu'Excel a un jour touchées, y compris celles qui ne portent qu'un formatage, et elle ne rétrécit pas quand vous supprimez des lignes tant que le classeur n'est pas enregistré ou recalculé. Elle surestime : une boucle sur UsedRange peut donc s'échiner sur des centaines de lignes fantômes. Elle ne commence pas non plus forcément à la ligne 1 (voir la FAQ). Considérez UsedRange comme « à peu près toute la feuille », jamais comme un numéro de dernière ligne précis.

.Find — la seule méthode à l'épreuve des trous. Rechercher à rebours la dernière cellule contenant quoi que ce soit, où que ce soit sur la feuille est insensible aux vides internes comme à la colonne choisie :

Function LastDataRow(ws As Worksheet) As Long
    Dim c As Range
    Set c = ws.Cells.Find(What:="*", After:=ws.Cells(1, 1), _
                          LookIn:=xlFormulas, SearchOrder:=xlByRows, _
                          SearchDirection:=xlPrevious)
    If c Is Nothing Then
        LastDataRow = 0            ' feuille vide
    Else
        LastDataRow = c.Row
    End If
End Function

.Find est verbeuse et vous devez gérer le cas Nothing (une feuille vide), mais c'est la bonne réponse quand vos données ont des bords irréguliers ou des trous internes. LookIn:=xlFormulas trouve les cellules dotées d'une formule même si elle s'évalue actuellement à "" ; xlValues les ignore — choisissez délibérément.

Le bon jugement : quelle méthode, et quand

  • Liste propre sur une seule colonne, ou tableau avec une colonne clé bien remplieCells(Rows.Count, keyCol).End(xlUp).Row. Rapide, lisible, correct.
  • Données avec des lignes vides internes ou un bord droit irrégulier.Find(What:="*", SearchDirection:=xlPrevious). À l'épreuve des trous.
  • « Quelle est en gros la taille de tout ce qui est sur cette feuille, pour que je puisse l'effacer ».UsedRange. La surestimation est sans danger quand vous effacez.
  • N'utilisez jamais .End(xlDown) pour la dernière ligne, et ne lisez jamais UsedRange.Rows.Count comme s'il s'agissait du numéro de la dernière ligne.

Trouver aussi la dernière colonne

Le même truc du bond fonctionne à l'horizontale. Partez de la cellule tout à droite de votre ligne d'en-tête et appuyez sur Ctrl+← dans le code :

Dim lastCol As Long
lastCol = Cells(1, Columns.Count).End(xlToLeft).Column

Avec les deux nombres, vous pouvez construire la plage exacte des données sans rien coder en dur :

Dim rng As Range
Set rng = ws.Range(ws.Cells(1, 1), ws.Cells(lastRow, lastCol))

C'est tout l'intérêt : une fois que vous savez trouver les bords, vous ne tapez plus jamais une adresse fixe. Pour construire une plage qui saute la ligne d'en-tête, associez ceci à Offset et Resize ; pour saisir le bloc contigu en un seul appel, voyez UsedRange contre CurrentRegion.

Comment ExcelMaster aide

Presque toute question « trouver la dernière ligne » est en réalité une étape vers un objectif plus large : boucler sur cette colonne et signaler les doublons, copier les nouvelles lignes vers une autre feuille, sommer par groupe. ExcelMaster prend cet objectif en langage courant — « pour chaque ligne du tableau des commandes, copie celles qui ne sont pas terminées vers la feuille Backlog » — et écrit le calcul de plage à votre place, en trouvant les bords des données de façon robuste plutôt qu'en supposant une taille fixe.

Vous écrirez encore .End(xlUp) à la main dans une macro qui tourne à heure fixe. Mais pour la tâche quotidienne « traite les lignes présentes aujourd'hui, quelles qu'elles soient », décrire le résultat vaut mieux que de réussir à chaque fois Rows.Count et la gestion des trous.

Questions fréquentes

Quelle est la meilleure façon de trouver la dernière ligne en VBA ?

Pour un tableau doté d'une colonne clé toujours remplie, utilisez Cells(Rows.Count, keyColumn).End(xlUp).Row. Elle imite Ctrl+↑ depuis le bas de la feuille : rapide et lisible. Si vos données comportent des lignes vides internes ou un bord irrégulier, utilisez plutôt Cells.Find(What:="*", SearchDirection:=xlPrevious).Row, car .End peut s'arrêter à un trou.

Pourquoi utiliser Rows.Count plutôt que 65536 ?

65536 était la dernière ligne de l'ancien format .xls. Les feuilles .xlsx modernes comptent 1 048 576 lignes : démarrer votre remontée à 65 536 commence donc au-dessus de toute donnée située sous ce point et renvoie une dernière ligne trop petite. Rows.Count reflète toujours la taille réelle de la feuille en cours.

Pourquoi UsedRange donne-t-il une mauvaise dernière ligne ?

UsedRange est une boîte englobante mise en cache regroupant toutes les cellules qu'Excel a un jour touchées, cellules au formatage seul comprises, et elle ne rétrécit pas quand vous supprimez des données tant que le fichier n'est pas enregistré. Elle peut aussi ne pas commencer à la ligne 1 : UsedRange.Rows.Count est donc un nombre, pas le numéro de la dernière ligne. Utilisez .End(xlUp) ou .Find pour une dernière ligne précise.

Comment trouver la dernière colonne en VBA ?

Reproduisez l'idiome de la dernière ligne à l'horizontale : Cells(1, Columns.Count).End(xlToLeft).Column. Il saute depuis la cellule tout à droite de la ligne d'en-tête jusqu'à la dernière colonne contenant quelque chose.

Comment trouver la dernière ligne quand la colonne contient des vides ?

.End(xlUp) n'inspecte qu'une seule colonne : un vide dans la dernière ligne de données de cette colonne la fait s'arrêter trop tôt. Soit vous la pointez sur une colonne toujours remplie (un identifiant), soit vous utilisez Cells.Find(What:="*", SearchDirection:=xlPrevious).Row, qui trouve la dernière cellule remplie n'importe où sur la feuille, quels que soient les trous.

Testé dans

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

Guides associés : VBA Offset · VBA UsedRange contre CurrentRegion · VBA Range · VBA For Loop