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 estCells(Rows.Count, "A").End(xlUp).Row— il simule l'appui surCtrl+↑depuis tout en bas de la colonne. UtilisezRows.Count, jamais un65536codé 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,.UsedRangesurestime, et.Findest 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
65536est une mine etRows.Countla 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
- 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
remplie →
Cells(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 jamaisUsedRange.Rows.Countcomme 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
