Ta macro fonctionne sur les commandes de cette semaine, puis oublie les lignes ajoutées la semaine suivante. Le problème vient souvent d'une limite écrite en dur, comme A2:D100. Pour traiter un tableau qui grandit, il faut commencer par trouver sa dernière ligne utile.
La méthode courante en VBA est Cells(Rows.Count, "A").End(xlUp).Row. Elle devient fiable quand tu précises la feuille et le rôle de la colonne A. Si tu démarres en programmation, le guide pour créer une première macro Excel explique l'accès à l'éditeur et aux modules.
- Trouver la dernière ligne d'une colonne avec End(xlUp).
- Cibler une feuille sans dépendre de l'onglet actif.
- Gérer une colonne vide ou limitée à son en-tête.
- Choisir Find ou un tableau structuré lorsque la colonne repère ne suffit pas.
La dernière ligne dépend de ce que tu cherches
Il n'existe pas une dernière ligne universelle pour tous les usages. Tu peux chercher la dernière commande identifiée, la dernière cellule contenant une formule ou la dernière ligne visible après un filtre. Ces trois questions peuvent donner des numéros différents dans le même classeur.
Notre cas concerne un export de commandes dans une feuille nommée Commandes. Les en-têtes sont en ligne 1. La colonne A contient les identifiants ; les colonnes B à D contiennent la date, le client et le montant. Une commande valide possède toujours son identifiant. C'est cette règle qui fait de A une bonne colonne repère.
Étape 1 : choisir une colonne vraiment renseignée
Dans une copie de ton fichier, prépare quelques commandes jusqu'à la ligne 8. Laisse volontairement la ligne 5 vide. Avec une recherche qui part du bas de la feuille, ce trou au milieu ne doit pas empêcher de trouver la commande de la ligne 8.
Vérifie aussi la fin des autres colonnes. Une note en D12 sans identifiant en A12 ne sera pas détectée par la recherche sur A. Ce n'est pas un défaut d'Excel : tu lui as demandé la fin de la colonne des identifiants. Si des lignes métier peuvent exister sans identifiant, choisis une autre règle avant d'utiliser le résultat dans une boucle.
Ne prends pas une colonne contenant des formules recopiées très loin uniquement parce qu'elle est pratique. Une cellule qui contient une formule reste occupée, même lorsque son résultat affiche une chaîne vide. Le dernier numéro détecté peut alors être très éloigné de la dernière commande réelle.
Étape 2 : coller une macro qui cible la bonne feuille
Dans Excel de bureau sous Windows, ouvre le classeur concerné, puis l'éditeur Visual Basic avec Alt + F11. Utilise Insertion, Module et colle la procédure ci-dessous. Elle lit un numéro et l'affiche : elle ne supprime aucune donnée et n'écrit pas dans les cellules.
Option Explicit
Sub LireDerniereCommande()
Dim ws As Worksheet
Dim derniereLigne As Long
Set ws = ThisWorkbook.Worksheets("Commandes")
If Application.WorksheetFunction.CountA(ws.Columns("A")) = 0 Then
MsgBox "La colonne A est vide."
Exit Sub
End If
derniereLigne = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
If derniereLigne < 2 Then
MsgBox "Il y a un en-tete, mais aucune commande."
Exit Sub
End If
MsgBox "Derniere ligne : " & derniereLigne
End Sub
Remplace uniquement le nom Commandes si ton onglet porte un autre nom. ThisWorkbook désigne le classeur qui contient le code. Place donc ce module dans le fichier à analyser, pas dans un autre classeur ni dans le classeur personnel de macros.
Le type Long convient à un numéro de ligne Excel. Integer est trop limité pour parcourir une grande feuille. Le code n'a pas besoin de sélectionner la feuille ou de déplacer le curseur pour lire la position recherchée.
Étape 3 : comprendre les trois morceaux de la ligne
Dans ws.Cells(ws.Rows.Count, "A"), ws.Rows.Count fournit le nombre de lignes de la feuille ciblée. Cells désigne ensuite la cellule de la colonne A située tout en bas. Les deux références utilisent la même variable ws : changer l'onglet actif ne doit pas changer la feuille analysée.
.End(xlUp) remonte vers une limite de zone, à la manière d'un déplacement clavier. En partant d'une cellule vide en bas, on rejoint la dernière cellule occupée de la colonne. .Row récupère son numéro, sans récupérer sa valeur. La référence Microsoft sur Range.End décrit cette propriété.
Le code suppose que la toute dernière ligne physique de la feuille n'est pas utilisée. Si ton export remplit réellement la feuille jusqu'en bas, cette hypothèse ne tient plus : utilise une recherche explicite, comme la variante Find plus bas, ou répartis les données dans un outil adapté à ce volume.
Étape 4 : vérifier les cas qui font dérailler les macros
Commence avec l'exemple des commandes jusqu'à la ligne 8 : le résultat attendu est 8 malgré le trou en ligne 5. Ajoute une commande avec identifiant en A12, relance : le résultat attendu devient 12. Efface cette commande, puis relance pour vérifier le retour à 8.
Sur une feuille ne contenant que l'en-tête en A1, la procédure affiche qu'aucune commande n'est présente. Si A est entièrement vide, le premier contrôle arrête la macro. Sans ces contrôles, la valeur 1 pourrait être prise à tort pour une ligne de données et produire une plage incohérente comme A2:A1.
Fais ensuite un essai en laissant un autre onglet actif. Le résultat doit toujours provenir de Commandes. Si Excel signale que l'indice n'appartient pas à la sélection, vérifie d'abord le nom de l'onglet et le classeur contenant le module. Une faute de nom ne se corrige pas en remplaçant toutes les références par ActiveSheet.
Étape 5 : réutiliser le numéro sans figer une plage
Une fois le numéro contrôlé, tu peux construire une plage telle que ws.Range("A2:D" & derniereLigne). Le numéro s'adapte à la source au lieu d'imposer une fin à la ligne 100. Place cette construction après les contrôles de colonne vide et d'absence de commande.
La variable indique une position, pas un nombre de commandes. Si des lignes sont vides au milieu, derniereLigne - 1 compte aussi ces trous. Pour compter les identifiants réellement renseignés, utilise un comptage adapté aux cellules, puis compare-le à la source.
Si un filtre masque des commandes, End(xlUp) ne représente pas le contrat « dernière ligne visible ». Une macro qui traite seulement les lignes affichées doit construire explicitement sa sélection visible. Conserve cette distinction quand tu combines le code avec les filtres d'Excel.
Quand utiliser Find à la place
Si aucune colonne n'est toujours renseignée, cherche la dernière cellule occupée sur la zone métier A:D. Le bloc suivant s'insère dans une procédure qui a déjà défini ws. Il précise les paramètres de recherche pour éviter de reprendre ceux laissés dans la fenêtre Rechercher.
Dim derniereCellule As Range
Set derniereCellule = ws.Range("A:D").Find( _
What:="*", After:=ws.Range("A1"), _
LookIn:=xlFormulas, LookAt:=xlPart, _
SearchOrder:=xlByRows, SearchDirection:=xlPrevious, _
MatchCase:=False, MatchByte:=False, SearchFormat:=False)
If derniereCellule Is Nothing Then
MsgBox "La zone A:D est vide."
Else
MsgBox "Derniere ligne de la zone : " & derniereCellule.Row
End If
LookIn:=xlFormulas considère les formules présentes, même si elles affichent du vide. Ce choix est volontaire : on cherche ici une cellule contenant quelque chose, pas forcément un identifiant visible. La recherche est limitée à A:D pour qu'une note placée ailleurs ne repousse pas artificiellement la limite.
Le retour de Find peut être Nothing ; le contrôle évite de lire la propriété Row sur un résultat inexistant. La documentation Microsoft de Find détaille ces paramètres et la mémorisation de certains réglages.
Le résultat : une limite expliquée, pas devinée
Ta macro possède maintenant une règle claire : la dernière commande est la dernière cellule occupée de la colonne des identifiants. Pour un simple tableau de saisie, un tableau structuré Excel peut être encore plus pratique, car ses lignes de données forment déjà une zone explicite.
Pour aller plus loin
Le choix entre End, Find et un tableau structuré dépend du fichier. Sur un export stable avec identifiant obligatoire, End suffit souvent. Pour comprendre comment cette information s'intègre à des boucles ou à un traitement plus large, retrouve les bases dans apprendre le VBA dans Excel. Garde le message de contrôle pendant la préparation, puis adapte seulement le traitement qui utilise la plage.
Questions fréquentes
Quelle est la formule VBA pour la dernière ligne non vide ?
Dans une colonne repère, utilise ws.Cells(ws.Rows.Count, "A").End(xlUp).Row après avoir défini ws. La dernière ligne physique doit rester vide pour cette méthode de départ par le bas. Vérifie aussi le cas où la colonne ne contient aucune donnée.
Pourquoi utiliser Long plutôt que Integer ?
Un numéro de ligne peut dépasser la capacité du type Integer. Long permet de stocker les numéros de lignes d'une feuille Excel. Cela évite un dépassement de capacité sur les exports importants.
Les lignes vides au milieu posent-elles problème ?
Avec un départ depuis le bas d'une colonne, un trou intermédiaire n'empêche pas de rejoindre la dernière cellule occupée. Il faut néanmoins que la colonne choisie identifie bien toutes les lignes utiles. Les trous restent présents dans la plage construite ensuite.
Une formule qui renvoie du vide est-elle ignorée ?
Non, une cellule contenant une formule reste occupée pour cette approche. Une colonne de formules préremplies peut donc produire un numéro trop bas dans la feuille. Choisis plutôt une colonne d'identifiants ou une règle de recherche adaptée.
Comment trouver la dernière ligne sur plusieurs colonnes ?
Utilise Find sur la zone concernée, avec les paramètres de recherche précisés et un contrôle du résultat Nothing. La variante de cet article cherche sur A:D et inclut les formules. Elle ne cherche pas uniquement les lignes visibles.
Ce code fonctionne-t-il dans Excel pour le Web ?
Excel pour le Web n'exécute pas les macros VBA. Le parcours décrit concerne Excel de bureau sous Windows. Les automatisations web utilisent d'autres mécanismes et demandent une adaptation.
