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

VBA Selection dans Excel — travailler avec ce qui est en surbrillance (et pourquoi ce n'est pas toujours une Range)

|

VBA Selection dans Excel — travailler avec ce qui est en surbrillance (et pourquoi ce n'est pas toujours une Range)

TL;DRSelection est un pointeur vivant vers ce qui est en surbrillance à cet instant. La plupart du temps c'est un Range — une cellule ou plusieurs — que vous pouvez donc parcourir, sommer ou mettre en forme. Mais Selection peut tout aussi bien être un graphique, une forme, ou un groupe d'objets, et alors un code comme For Each c In Selection ou Selection.Value déclenche une erreur d'exécution. Le réflexe professionnel tient en deux temps : protégez-vous avec TypeName(Selection) = "Range" avant de toucher aux cellules, et pour tout ce qui n'est pas un outil piloté par l'utilisateur, n'utilisez pas Selection du tout — nommez la plage que vous visez.

Sub SumTheSelection()
    ' Protégez-vous d'abord : Selection n'est pas toujours une plage
    If TypeName(Selection) <> "Range" Then
        MsgBox "Select some cells first.", vbExclamation
        Exit Sub
    End If

    Dim cell As Range, total As Double
    For Each cell In Selection.Cells
        If IsNumeric(cell.Value) Then total = total + cell.Value
    Next cell
    MsgBox "Sum of selection: " & total
End Sub

Selection paraît simple — c'est « ce que j'ai mis en surbrillance » — et pour un outil rapide qui agit sur ce que l'utilisateur a choisi, c'est exactement ce qu'il faut. Les ennuis commencent quand le code suppose que la sélection est un bloc de cellules bien rangé. Souvent, elle ne l'est pas, et l'échec est un plantage franc plutôt qu'un résultat erroné. Ce guide explique ce que Selection peut réellement être, et comment traiter chaque cas.

Ce que vous allez apprendre

  • Le modèle mental — un pointeur vivant vers la surbrillance, pas une plage que vous avez nommée
  • La règle qui le rend utile — le plus souvent une plage que vous pouvez parcourir
  • La règle qui fait planter le code — Selection n'est pas toujours une plage
  • Selection contre ActiveCell — toute la surbrillance contre l'unique ancre
  • Les sélections multi-zones — le piège de .Areas avec le Ctrl-clic
  • La leçon plus large — référencez les plages explicitement pour du code non interactif

Le modèle mental : un pointeur vivant vers la surbrillance

Comme ActiveCell, Selection n'a aucune identité fixe. Ce n'est pas une cellule ou une plage que vous avez déclarée — c'est la réponse d'Excel à la question « qu'est-ce qui est en surbrillance dans la fenêtre active à cet instant ? ». Cliquez sur une autre cellule et Selection désigne autre chose. Lancez une macro le lundi avec une colonne en surbrillance et le mardi avec un graphique sélectionné, et Selection est un Range un jour, un Chart le lendemain.

Voilà ce qui rend Selection puissant pour les outils — un bouton qui met en forme « ce que j'ai choisi » a précisément besoin de cela — et dangereux pour l'automatisation, où la surbrillance est ce que l'utilisateur a laissé au hasard. La chose la plus importante à savoir sur Selection, c'est que vous ne contrôlez pas son type.

La règle qui le rend utile : le plus souvent une plage que vous pouvez parcourir

Quand la sélection est faite de cellules, Selection est un Range, et toutes les astuces de plage s'appliquent. Le motif le plus courant est de parcourir les cellules sélectionnées :

Sub HighlightNegatives()
    Dim cell As Range
    For Each cell In Selection.Cells
        If IsNumeric(cell.Value) Then
            If cell.Value < 0 Then cell.Interior.Color = vbRed
        End If
    Next cell
End Sub

Membres utiles quand la sélection est une plage :

  • Selection.Cells.Count — combien de cellules sont en surbrillance
  • Selection.Rows.Count / Selection.Columns.Count — sa forme
  • Selection.Address — l'adresse en surbrillance, p. ex. $B$2:$D$10
  • Selection.Value — mais n'a de sens que pour une seule cellule ; sur une sélection de plusieurs cellules il renvoie un tableau 2D, et affecter x = Selection.Value à un scalaire ne vous donne que la première cellule, ou une erreur

Ce dernier point est le plus discret : Selection.Value ne vous donne pas « la somme » ni « les valeurs » d'un bloc de la façon qu'attendent la plupart des débutants. Pour travailler sur une sélection de plusieurs cellules, parcourez-la (comme ci-dessus) ou lisez-la dans un tableau.

La règle qui fait planter le code : Selection n'est pas toujours une Range

C'est le bug numéro un de Selection. Votre macro parcourt la sélection, fonctionne parfaitement pendant des semaines, puis un utilisateur la lance avec un graphique cliqué et elle meurt sur « Cette propriété ou méthode n'est pas gérée par cet objet » (erreur 438) ou « Objet requis » (erreur 424). Rien n'est cassé — la sélection n'est simplement pas une plage :

' Ce que Selection peut être, selon ce qui est cliqué :
'   des cellules       -> Range
'   un objet graphique -> ChartObject / Chart
'   une forme          -> Shape
'   plusieurs objets   -> DrawingObjects
'   rien d'exploitable -> dépend du contexte

La solution est une protection d'une ligne en tête de toute macro qui attend des cellules — vérifiez le type avant d'y toucher :

Sub NeedsCells()
    If TypeName(Selection) <> "Range" Then
        MsgBox "This tool works on cells. Select a range first.", vbExclamation
        Exit Sub
    End If
    ' ...on peut traiter Selection comme un Range à partir d'ici, sans risque...
End Sub

TypeName(Selection) renvoie la chaîne "Range" quand des cellules sont en surbrillance, et "ChartObject", "Rectangle", "Picture", etc. sinon. Faites de cette protection un réflexe dans tout outil fondé sur la sélection — c'est la différence entre une invite courtoise et un plantage au visage de l'utilisateur.

Selection contre ActiveCell : toute la surbrillance contre l'unique ancre

On les confond sans cesse, gardez donc la distinction nette :

Selection ActiveCell
Portée Toute la surbrillance L'unique cellule d'ancrage
Nombre Une ou plusieurs cellules (ou un objet non-cellule) Toujours exactement une cellule
Toujours une plage ? Non — peut être une forme/un graphique Uniquement une cellule (erreur sur une feuille graphique)
Lire .Value Un tableau sur plusieurs cellules Toujours une seule valeur
À utiliser pour « Tout ce que l'utilisateur a choisi » « L'unique cellule active »

Ils fonctionnent ensemble : ActiveCell est l'ancre à l'intérieur de Selection. Voyez VBA ActiveCell pour le versant « une seule cellule » du duo.

Le piège des zones multiples : le Ctrl-clic crée plusieurs Areas

Il existe un problème de forme plus subtil même quand Selection est une plage. Si l'utilisateur fait un Ctrl-clic pour mettre en surbrillance A1:A5 et C1:C5, c'est une seule sélection composée de deux zones. Une simple boucle sur Selection.Cells visite quand même chaque cellule — mais un code qui raisonne sur « la plage » (son adresse, ses angles, Selection.Rows.Count) peut se tromper, car ces éléments ne s'appliquent qu'à la première zone :

Sub WalkAllAreas()
    Dim area As Range, cell As Range
    Debug.Print "Areas selected: " & Selection.Areas.Count   ' p. ex. 2
    For Each area In Selection.Areas
        For Each cell In area.Cells
            ' ...traiter chaque cellule de chaque zone...
        Next cell
    Next area
End Sub

La règle : quand une sélection peut être non contiguë, parcourez Selection.Areas, pas seulement Selection. C'est la même famille de bug « la forme n'est pas celle que je supposais » que le cas « pas une plage » ci-dessus.

La leçon plus large : nommez la plage pour du code non interactif

Tout ce qui précède concerne le maniement sûr de Selection — mais la leçon plus profonde est de savoir quand l'éviter. Selection dépend entièrement de l'état de l'interface, change sous vos pieds, et ne signifie rien quand une macro s'exécute sans surveillance. Donc :

  • Utilisez Selection pour de véritables outils interactifs — un bouton du ruban, un assistant de clic droit, une macro « mets en forme ce que j'ai choisi ». Là, « ce que l'utilisateur a mis en surbrillance » est l'entrée.
  • N'utilisez pas Selection pour de l'automatisation qui vise des données connues. Référencez la plage directement — Worksheets("Data").Range("A1:A100") — pour que la macro soit indépendante de l'endroit où se trouve le curseur.

C'est le même principe que de ne pas sélectionner les cellules avant d'agir dessus, traité dans VBA Select vs Activate : moins vos macros dépendent de la sélection en cours, moins elles cassent quand un utilisateur clique à un endroit inattendu.

Comment ExcelMaster aide

Les pièges de Selection — un graphique au lieu de cellules, un Ctrl-clic qui se scinde en zones, un Selection.Value qui n'est pas la valeur que vous croyiez — compilent tous sans problème et ne mordent qu'à l'exécution, sur le clic de quelqu'un d'autre. Écrire à la main les protections et les boucles sur les zones est fastidieux et facile à oublier.

ExcelMaster vous laisse décrire l'outil à la place. Demandez « un bouton qui additionne les cellules que j'ai sélectionnées », et il écrit pour vous la protection TypeName et la boucle consciente des zones ; demandez « nettoie la colonne A de la feuille Data », et il ignore complètement Selection pour référencer la plage directement. Vous gardez une macro lisible sans avoir à vous souvenir de toutes les façons dont une sélection peut vous surprendre.

Questions fréquentes

Comment parcourir les cellules sélectionnées en VBA ?

Utilisez For Each cell In Selection.Cells. Par exemple : For Each cell In Selection.Cells: Debug.Print cell.Address: Next cell. Protégez-vous d'abord avec If TypeName(Selection) <> "Range" Then Exit Sub, car une boucle sur une sélection qui n'est pas une plage (comme un graphique) déclenche une erreur. Pour les sélections au Ctrl-clic, parcourez Selection.Areas, puis les cellules de chaque zone.

Pourquoi mon code Selection donne-t-il l'erreur 438 ou 424 ?

Parce que Selection n'est pas un Range à ce moment-là — un graphique, une forme ou un autre objet a été sélectionné à la place des cellules, et il ne prend pas en charge les membres de plage comme .Cells ou .Value. Ajoutez If TypeName(Selection) <> "Range" Then Exit Sub en tête de la macro pour qu'elle sorte proprement (ou avertisse l'utilisateur) au lieu de planter.

Quelle est la différence entre Selection et ActiveCell ?

Selection est toute la zone en surbrillance et peut compter plusieurs cellules — voire une forme ou un graphique. ActiveCell est toujours l'unique cellule d'ancrage à l'intérieur de cette sélection. Utilisez ActiveCell pour l'unique cellule active et Selection quand vous avez besoin de tout ce que l'utilisateur a mis en surbrillance.

Comment obtenir le nombre de cellules sélectionnées ?

Utilisez Selection.Cells.Count pour le nombre total de cellules, Selection.Rows.Count et Selection.Columns.Count pour sa forme, et Selection.Areas.Count pour savoir s'il s'agit d'un seul bloc ou d'un Ctrl-clic de plusieurs zones. Rappelez-vous que les décomptes de lignes/colonnes ne décrivent que la première zone lorsque la sélection est non contiguë.

Faut-il utiliser Selection ou référencer la plage directement ?

N'utilisez Selection que pour les outils interactifs qui agissent sur « ce que l'utilisateur a choisi ». Pour de l'automatisation qui vise des données connues, référencez la plage explicitement — par exemple Worksheets("Data").Range("A1:A100") — pour que la macro ne dépende pas de l'endroit où se trouve le curseur et ne puisse pas agir sur les mauvaises cellules.

Testé dans

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

Guides associés : VBA ActiveCell · VBA Select vs Activate · VBA Range · VBA For Each · VBA Worksheet_SelectionChange