TL;DR —
ActiveCelln'est pas une cellule que vous avez choisie dans le code ; c'est un pointeur vivant vers l'unique cellule qui a le curseur à cet instant. Il y a toujours exactement une cellule active, elle se trouve sur la feuille active, et elle est toujours à l'intérieur de laSelectioncourante (c'est l'ancre de la sélection). Cela le rend parfait pour « faire quelque chose là où se trouve l'utilisateur » — et fragile pour tout le reste, car il se déplace dès que la feuille active ou le curseur change, et il n'existe pas du tout sur une feuille graphique.
Sub ReadAndWriteActiveCell()
' Lire la cellule active
MsgBox "You are on " & ActiveCell.Address & _
", value = " & ActiveCell.Value
' L'écrire, puis marquer la cellule à sa droite
ActiveCell.Value = "Reviewed"
ActiveCell.Offset(0, 1).Value = Now ' une colonne à droite, même ligne
End Sub
La plupart des débutants rencontrent ActiveCell via l'enregistreur de macros, où il
apparaît comme « la cellule que je viens de cliquer ». Cette présentation masque ce
qu'il est vraiment — un pointeur qui suit le curseur — et cet écart est à la source de
presque tous les bugs d'ActiveCell. Maîtrisez le modèle mental et la puissance comme
les pièges deviennent évidents.
Ce que vous allez apprendre
- Le modèle mental — un pointeur vivant vers le curseur, pas une cellule que vous avez nommée
- La règle qui le définit — exactement une cellule active, toujours à l'intérieur de la Selection
ActiveCellcontreSelection— une cellule contre toute la surbrillance- Le lire et l'écrire sans risque —
.Value,.Offset,.Row/.Column - Le mode de défaillance numéro un — il suit la feuille active et le curseur
- Quand l'utiliser, et quand référencer une plage explicitement à la place
Le modèle mental : un pointeur vivant, pas une cellule que vous avez choisie
Quand vous écrivez Range("A1"), vous nommez une cellule fixe — elle désigne A1 quoi
qu'il arrive. ActiveCell, c'est l'inverse : il signifie « là où se trouve le
curseur », et cela peut changer à chaque exécution de la macro. C'est un pointeur
qu'Excel garde braqué sur l'unique cellule où l'utilisateur (ou votre dernière commande
de navigation) a laissé le curseur.
ActiveCell n'a donc aucune identité fixe. Lancez la même macro avec le curseur sur
C5 et elle agit sur C5 ; lancez-la avec le curseur sur Z99 et elle agit sur Z99.
C'est tout son intérêt — il permet à un outil d'agir sur « ici » sans connaître
l'adresse à l'avance — mais cela signifie aussi que la cellule qu'il désigne est
déterminée par l'état de l'interface, pas par votre code. Gardez cette idée en tête ;
c'est la racine du principal mode de défaillance décrit plus bas.
La règle qui le définit : une cellule active, toujours à l'intérieur de la Selection
Deux faits cernent exactement ce qu'est ActiveCell :
- Il y a toujours exactement une cellule active sur la feuille active — jamais
zéro, jamais deux. Même quand un grand bloc comme
B2:D10est sélectionné, une cellule à l'intérieur (celle qui reste blanche pendant que le reste est ombré) est la cellule active. C'est cette ancre que renvoieActiveCell. - La cellule active est toujours à l'intérieur de la sélection courante.
Sélectionnez
B2:D10et la cellule active se trouve quelque part dans ce bloc (B2par défaut). Elle ne peut jamais être une cellule en dehors de la surbrillance.
Sub SelectionAnchor()
Range("B2:D10").Select
MsgBox "Selection: " & Selection.Address & vbCrLf & _
"ActiveCell: " & ActiveCell.Address ' -> $B$2, l'ancre
End Sub
Cette relation est la clé pour ne pas confondre les deux : Selection est toute la
surbrillance ; ActiveCell est l'unique ancre à l'intérieur.
ActiveCell contre Selection : une cellule contre toute la surbrillance
C'est la distinction qui fait trébucher, elle mérite donc une comparaison côte à côte :
ActiveCell |
Selection |
|
|---|---|---|
| Combien de cellules | Toujours exactement une | Une ou plusieurs (ou un objet non-cellule) |
| Ce qu'il renvoie | Un Range d'une seule cellule |
Généralement un Range, mais parfois une Shape/un Chart |
| Relation | L'ancre à l'intérieur de la sélection | Toute la zone en surbrillance |
| Usage typique | « Agir sur la cellule active » | « Agir sur tout ce que l'utilisateur a sélectionné » |
.Value sur plusieurs cellules |
Toujours une seule valeur | Erreur, ou renvoie seulement la première cellule |
La règle pratique : si vous voulez l'unique cellule où se trouve l'utilisateur,
utilisez ActiveCell. Si vous voulez parcourir tout ce qu'il a mis en
surbrillance, utilisez Selection (et voyez le guide compagnon,
VBA Selection, pour son propre piège — ce n'est pas toujours
une plage).
Le lire et l'écrire sans risque
Une fois que vous savez que c'est un Range d'une seule cellule, tout ce qu'une plage
sait faire, ActiveCell sait le faire :
Sub ActiveCellMembers()
ActiveCell.Value = 42 ' écrire la valeur
Debug.Print ActiveCell.Value ' la relire
Debug.Print ActiveCell.Row ' le numéro de ligne, p. ex. 5
Debug.Print ActiveCell.Column ' le numéro de colonne, p. ex. 3
Debug.Print ActiveCell.Address ' "$C$5"
ActiveCell.Offset(1, 0).Value = "below" ' la cellule une ligne en dessous
ActiveCell.Offset(0, -1).Value = "left" ' la cellule une colonne à gauche
End Sub
Offset est le cheval de bataille ici : ActiveCell.Offset(rowDelta, colDelta)
renvoie une cellule nouvelle, relative au curseur, sans le déplacer — c'est
exactement ainsi qu'on écrit « la cellule à côté de là où je suis ». (Pour le tableau
complet du déplacement relatif et le piège du décalage d'une unité, voyez
VBA Offset.)
Une protection à intégrer : si votre macro suppose qu'une vraie cellule est
sélectionnée, vérifiez-le d'abord. Quand un graphique ou une forme est sélectionné,
Selection n'est plus une plage, et sur une feuille graphique ActiveCell déclenche
carrément une erreur d'exécution :
Sub SafeActiveCell()
If TypeName(Selection) <> "Range" Then
MsgBox "Please click a cell first.", vbExclamation
Exit Sub
End If
ActiveCell.Value = "OK"
End Sub
Le mode de défaillance numéro un : il suit la feuille active et le curseur
Voici le bug qui remplit les forums. Vous écrivez une macro censée journaliser quelque
chose sur une feuille « Log », et vous recourez à ActiveCell :
' FRAGILE : écrit là où se trouve le curseur, quel qu'il soit
Sub LogEntryWrong()
ActiveCell.Value = "Entry at " & Now
End Sub
Si l'utilisateur la lance alors qu'il est sur la feuille Dashboard, elle écrit sur le
Dashboard — par-dessus de vraies données — car ActiveCell est le curseur sur la
feuille active, pas « une cellule sur la feuille Log ». La macro n'a pas mal
fonctionné ; elle a fait exactement ce que ActiveCell signifie. La solution est
d'arrêter d'utiliser ActiveCell pour du code qui ne concerne pas l'endroit où se
trouve l'utilisateur, et de nommer la cible explicitement :
' ROBUSTE : toujours la cellule voulue, quel que soit le curseur
Sub LogEntryRight()
Dim nextRow As Long
With Worksheets("Log")
nextRow = .Cells(.Rows.Count, "A").End(xlUp).Row + 1
.Cells(nextRow, "A").Value = "Entry at " & Now
End With
End Sub
La règle à intérioriser : ActiveCell ne sert que pour les outils qui agissent sur
« la cellule courante de l'utilisateur » — un bouton du ruban, un assistant de clic
droit, un raccourci de mise en forme rapide. Dès qu'une macro a besoin d'une cellule
précise et connue, référencez-la directement avec un Worksheets(...).Range(...)
qualifié. C'est le même réflexe que celui qui consiste à ne pas sélectionner les
cellules avant d'agir dessus — traité dans
VBA Select vs Activate.
Comment ExcelMaster aide
Les pièges d'ActiveCell sont subtils parce que le code s'exécute — il s'exécute
simplement sur la mauvaise cellule ou la mauvaise feuille, en silence. Savoir quand
« là où se trouve l'utilisateur » est la bonne ancre et quand c'est un handicap demande
de l'expérience.
ExcelMaster vous
laisse décrire le résultat à la place. Demandez « un bouton qui inscrit le nom du
relecteur sur la cellule sélectionnée », et il utilise ActiveCell là où c'est vraiment
ce que vous voulez ; demandez « ajouter une ligne à la feuille Log », et il écrit à la
place une référence qualifiée, indépendante du curseur — aucune écriture accidentelle
sur la feuille qui se trouvait ouverte. Le code reste le vôtre et vous pouvez en lire
chaque ligne.
Questions fréquentes
Quelle est la différence entre ActiveCell et Selection en VBA ?
ActiveCell est toujours une seule cellule — l'ancre qui a le curseur. Selection est
toute la zone en surbrillance, qui peut compter plusieurs cellules (voire une forme ou
un graphique). La cellule active est toujours à l'intérieur de la sélection. Utilisez
ActiveCell pour l'unique cellule active et Selection quand vous voulez travailler
sur tout ce que l'utilisateur a mis en surbrillance.
Comment obtenir la valeur de la cellule active en VBA ?
Utilisez ActiveCell.Value. Par exemple, MsgBox ActiveCell.Value affiche le contenu
de la cellule active, et x = ActiveCell.Value le stocke dans une variable. Pour
obtenir sa position à la place, utilisez ActiveCell.Row, ActiveCell.Column ou
ActiveCell.Address.
Comment référencer la cellule voisine de la cellule active ?
Utilisez Offset : ActiveCell.Offset(0, 1) est la cellule une colonne à droite,
ActiveCell.Offset(1, 0) une ligne en dessous, et ActiveCell.Offset(-1, 0) une ligne
au-dessus. Offset renvoie une nouvelle cellule sans déplacer le curseur, vous pouvez
donc la lire ou l'écrire directement, p. ex. ActiveCell.Offset(0, 1).Value = "done".
Pourquoi ma macro écrit-elle sur la mauvaise feuille quand j'utilise ActiveCell ?
Parce qu'ActiveCell renvoie toujours au curseur sur la feuille active du moment. Si
l'utilisateur lance la macro depuis une feuille différente de celle que vous imaginiez,
c'est là qu'elle écrit. Pour du code qui doit viser un emplacement précis,
référencez-le explicitement — par exemple Worksheets("Log").Range("A1") — au lieu de
vous fier à ActiveCell.
ActiveCell peut-il être vide ou Nothing ?
Une cellule active existe toujours sur une feuille de calcul (il n'existe pas d'« absence
de curseur »), donc ActiveCell n'est jamais Nothing en usage normal. Il peut pointer
vers une cellule vide — ActiveCell.Value renvoie alors une chaîne vide. L'exception
est la feuille graphique, où il n'y a aucune cellule et où référencer ActiveCell
déclenche une erreur d'exécution ; protégez-vous avec TypeName(Selection) = "Range" si
le cas est possible.
Testé dans
Testé dans : Excel 365 (Windows 11), VBA 7.1 — dernière vérification le 03/08/2026.
Guides associés : VBA Selection · VBA Select vs Activate · VBA Range · VBA Offset · VBA Worksheet
