Difference in type between using and not using Set keyword

calendar_today Asked Jun 18, 2012
thumb_up 14 upvotes
history Updated April 14, 2026

Direct Answer

This is why. When you say this: Dim startCell, iCell As Range you think you've done this: Dim startCell As Range, iCell As Range but what you've really done is this: Dim startCell…. This is a prose walkthrough, ranked #39th of 95 by community upvote score, from 2012.


The Problem (Q-score 5, ranked #39th of 95 in the VBA Core archive)

The scenario as originally posted in 2012

I just solved a problem I was having putting the “Set” keyword in a definition line but what I would like to know is “why” ?

Basically, I am doing this:

Dim startCell, iCell as Range
For Each iCell in Range(whatever)
    If iCell.value <>"" Then
        Set startCell = Cells(iCell.Row + 1, iCell.Column)
    End If
Next iCell

If I omit the “Set” keyword the code still compiles fine, but in the local variables window I see that its type changes to “String” instead of “Variant/Object/Range”. Why would that happen ?

Why community consensus is tight on this one

Across 95 VBA Core entries in the archive, the accepted answer here holds solid answer (above median) status — meaning voters are unusually aligned on the right fix.


The Verified Solution — solid answer (above median) (+14)

Verbal answer — walkthrough without a code block

Note: the verified answer is a prose walkthrough. If you need a runnable sample, check VBA Core entries ranked in the top 10 of the same archive.

This is why. When you say this:

Dim startCell, iCell As Range

you think you’ve done this:

Dim startCell As Range, iCell As Range

but what you’ve really done is this:

Dim startCell 'As Variant, by default
Dim iCell As Range

This is a classic VBA mistake. Most VBA programmers have made it, and that’s why most VBA programmers fall back on declaring only one variable per Dim statement (i.e. one per line). Otherwise it’s way too easy to make that mistake, and difficult to spot it afterwards.

So with Dim startCell you’ve implicitly declared your variable as Variant type (equivalent to Dim startCell As Variant).

When you then say this:

Set startCell = Cells(iCell.Row + 1, iCell.Column)

the Variant acquires the type of the thing on the right hand side of the reference assignment (Range). However, when you say this:

startCell = Cells(iCell.Row + 1, iCell.Column)

without the Set keyword, you’re not assigning a reference, but a value to the variable startCell, which now acquires the type of the value on the right hand side. What is that type? Well, the default property of a Range object is Value, so you’re going to get the type of Cells(iCell.Row + 1, iCell.Column).Value. If that cell contains a string, then you’ll get a string.


When to Use It — vintage (14+ years old, pre-2013)

Ranked #39th in its category — specialized fit

This pattern sits in the 89% tail relative to the top answer. Reach for it when your scenario closely matches the question title; otherwise browse the VBA Core archive for a higher-consensus alternative.

What changed between 2012 and 2026

The answer is 14 years old. The VBA Core object model has been stable across Office 2013, 2016, 2019, 2021, 365, and 2024/2026 LTSC, so the pattern still compiles. Changes that might affect you: 64-bit API declarations (use PtrSafe), blocked macros in downloaded files (Mark-of-the-Web), and the shift toward Office Scripts for web-first workflows.

help
Frequently Asked Questions

Is this above-median answer still worth copying?
expand_more

Answer score +14 vs the VBA Core archive median ~4; this entry is solid. The score plus 5 supporting upvotes on the question itself (+5) means the asker and 13 subsequent voters all validated the approach.

The answer has no code block — how do I turn it into a snippet?
expand_more

Use the walkthrough above as a checklist, then open a top-10 VBA Core archive entry for a concrete starting template you can adapt.

This answer is 14 years old. Is it still relevant in 2026?
expand_more

Published 2012, which is 14 year(s) before today’s Office 2026 build. The VBA Core object model has had no breaking changes in that window. Three things to re-test: (1) blocked macros on downloaded files (Mark-of-the-Web), (2) 64-bit API declarations (PtrSafe, LongPtr), (3) any shift toward Office Scripts for web scenarios.

Which VBA Core pattern ranks just above this one at #38?
expand_more

The pattern one rank above is “Deleting Empty rows in Excel using VBA”. If your use case overlaps, compare both before committing.

Data source: Community-verified Q&A snapshot. Q-score 5, Answer-score 14, original post 2012, ranked #39th of 95 in the VBA Core archive. Last regenerated April 14, 2026.

vba