TL;DR —
Selectionis a live pointer to whatever is highlighted right now. Most of the time that's aRange— one cell or many — so you can loop it, sum it, or format it. ButSelectioncan just as easily be a chart, a shape, or a group of objects, and then code likeFor Each c In SelectionorSelection.Valuethrows a run-time error. The professional habit is two-part: guard withTypeName(Selection) = "Range"before touching cells, and for anything that isn't a user-driven tool, don't useSelectionat all — name the range you mean.
Sub SumTheSelection()
' Guard first: Selection is not always a range
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 feels simple — it's "the stuff I highlighted" — and for a quick tool that
acts on whatever the user picked, it's exactly right. The trouble starts when code
assumes the selection is a tidy block of cells. It often isn't, and the failure is
a hard crash rather than a wrong answer. This guide is about knowing what Selection
can really be, and handling each case.
What you'll learn
- The mental model — a live pointer to the highlight, not a range you named
- The rule that makes it useful — usually a range you can loop
- The rule that crashes code —
Selectionisn't always a range SelectionvsActiveCell— the whole highlight vs the one anchor- Multi-area selections — the
.Areastrap with Ctrl-click - The bigger lesson — reference ranges explicitly for non-interactive code
The mental model: a live pointer to the highlight
Like ActiveCell, Selection has no fixed identity. It
isn't a cell or range you declared — it's Excel's answer to the question "what is
highlighted in the active window at this instant?" Click a different cell and
Selection means something else. Run a macro on Monday with a column highlighted and
on Tuesday with a chart selected, and Selection is a Range one day and a Chart
the next.
That's what makes Selection powerful for tools — a button that formats "whatever
I picked" needs exactly this — and dangerous for automation, where the highlight is
whatever the user happened to leave behind. The single most important thing to know
about Selection is that you don't control its type.
The rule that makes it useful: usually a range you can loop
When the selection is cells, Selection is a Range, and every range trick
applies. The most common pattern is looping the selected cells:
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
Useful members when the selection is a range:
Selection.Cells.Count— how many cells are highlightedSelection.Rows.Count/Selection.Columns.Count— its shapeSelection.Address— the highlighted address, e.g.$B$2:$D$10Selection.Value— but only meaningful for a single cell; on a multi-cell selection it returns a 2-D array, and assigningx = Selection.Valueinto a scalar gives you just the first cell or an error
That last point is the quiet one: Selection.Value does not give you "the sum"
or "the values" of a block in a way most beginners expect. To work across a
multi-cell selection you loop it (as above) or read it into an array.
The rule that crashes code: Selection isn't always a Range
This is the number-one Selection bug. Your macro loops the selection, works
perfectly for weeks, then a user runs it with a chart clicked and it dies with
"Object doesn't support this property or method" (error 438) or "Object
required" (error 424). Nothing is broken — the selection simply isn't a range:
' What Selection can be, depending on what's clicked:
' cells -> Range
' a chart object -> ChartObject / Chart
' a shape -> Shape
' several objects -> DrawingObjects
' nothing usable -> depends on context
The fix is a one-line guard at the top of any macro that expects cells — check the type before you touch it:
Sub NeedsCells()
If TypeName(Selection) <> "Range" Then
MsgBox "This tool works on cells. Select a range first.", vbExclamation
Exit Sub
End If
' ...safe to treat Selection as a Range from here...
End Sub
TypeName(Selection) returns the string "Range" when cells are highlighted, and
"ChartObject", "Rectangle", "Picture", and so on otherwise. Make this guard a
reflex in any selection-based tool — it's the difference between a friendly prompt
and a crash in the user's face.
Selection vs ActiveCell: the whole highlight vs the one anchor
They're constantly confused, so keep the split clear:
Selection |
ActiveCell |
|
|---|---|---|
| Scope | The entire highlight | The one anchor cell |
| Count | One or many cells (or a non-cell object) | Always exactly one cell |
| Always a range? | No — can be a shape/chart | Only a cell (errors on a chart sheet) |
Read .Value |
Array on multi-cell | Always a single value |
| Use it for | "Everything the user picked" | "The single focused cell" |
They work together: ActiveCell is the anchor inside Selection. See
VBA ActiveCell for the single-cell side of the pair.
The multi-area trap: Ctrl-click makes several Areas
There's a subtler shape problem even when Selection is a range. If the user
Ctrl-clicks to highlight A1:A5 and C1:C5, that's one selection made of two
areas. A single loop over Selection.Cells still visits every cell — but code that
reasons about "the range" (its address, its corners, Selection.Rows.Count) can get
the wrong answer, because those apply to the first area only:
Sub WalkAllAreas()
Dim area As Range, cell As Range
Debug.Print "Areas selected: " & Selection.Areas.Count ' e.g. 2
For Each area In Selection.Areas
For Each cell In area.Cells
' ...process each cell in each area...
Next cell
Next area
End Sub
The rule: when a selection might be non-contiguous, loop Selection.Areas, not
just Selection. It's the same class of "the shape isn't what I assumed" bug as the
non-range case above.
The bigger lesson: name the range for non-interactive code
Everything above is about handling Selection safely — but the deeper lesson is
knowing when to avoid it. Selection depends entirely on UI state, changes under
you, and means nothing when a macro runs unattended. So:
- Use
Selectionfor genuinely interactive tools — a ribbon button, a right-click helper, a "format what I picked" macro. There, "whatever the user highlighted" is the input. - Don't use
Selectionfor automation that targets known data. Reference the range directly —Worksheets("Data").Range("A1:A100")— so the macro is independent of where the cursor happens to be.
This is the same principle as not selecting cells before acting on them, covered in VBA Select vs Activate: the fewer of your macros that depend on the live selection, the fewer break when a user clicks somewhere unexpected.
How ExcelMaster helps
The Selection traps — a chart instead of cells, a Ctrl-click that splits into
areas, Selection.Value that isn't the value you meant — all compile fine and only
bite at run time, on someone else's click. Writing the guards and the area loops by
hand is fiddly and easy to forget.
ExcelMaster lets
you describe the tool instead. Ask for "a button that sums whatever cells I've got
selected," and it writes the TypeName guard and the area-aware loop for you; ask for
"clean column A on the Data sheet," and it skips Selection altogether and references
the range directly. You keep a readable macro without having to remember every way a
selection can surprise you.
Frequently asked questions
How do I loop through selected cells in VBA?
Use For Each cell In Selection.Cells. For example:
For Each cell In Selection.Cells: Debug.Print cell.Address: Next cell. Guard first
with If TypeName(Selection) <> "Range" Then Exit Sub, because a loop over a
non-range selection (like a chart) raises an error. For Ctrl-click selections, loop
Selection.Areas and then each area's cells.
Why does my Selection code give error 438 or 424?
Because Selection isn't a Range at that moment — a chart, shape, or other object
was selected instead of cells, and it doesn't support range members like .Cells or
.Value. Add If TypeName(Selection) <> "Range" Then Exit Sub at the top of the
macro so it exits cleanly (or prompts the user) instead of crashing.
What is the difference between Selection and ActiveCell?
Selection is the whole highlighted region and can be many cells — or even a shape or
chart. ActiveCell is always the single anchor cell inside that selection. Use
ActiveCell for the one focused cell and Selection when you need everything the
user highlighted.
How do I get the number of selected cells?
Use Selection.Cells.Count for the total number of cells, Selection.Rows.Count and
Selection.Columns.Count for its shape, and Selection.Areas.Count to see whether
it's a single block or a Ctrl-click of several areas. Remember the row/column counts
describe only the first area when the selection is non-contiguous.
Should I use Selection or reference the range directly?
Use Selection only for interactive tools that act on "whatever the user picked."
For automation that targets known data, reference the range explicitly — for example
Worksheets("Data").Range("A1:A100") — so the macro doesn't depend on where the
cursor is and can't act on the wrong cells.
Tested in
Tested in: Excel 365 (Windows 11), VBA 7.1 — last verified 2026-08-03.
Related guides: VBA ActiveCell · VBA Select vs Activate · VBA Range · VBA For Each · VBA Worksheet_SelectionChange
