In Excel VBA, a cell is represented by a Range object: use Range to refer to an address or block such as A1 or A1:C10, and use Cells(row, column) when numeric row-and-column indexing is more convenient. The key distinction is that Range is an object type, while Cells is a worksheet property that returns a Range object for the specified cell.
The short answer: a cell is a Range
VBA does not have a separate worksheet-cell object that you use instead of Range. A single cell, a rectangular block, an entire row, and an entire column can all be represented by Range objects. For example, Range("A1") refers to one cell, while Range("A1:C10") refers to 30 cells. The same is true of Cells(1, 1): it returns a Range object representing cell A1.
This explains why you can use many of the same properties and methods on either expression. For instance, both Range("A1").Value and Cells(1, 1).Value read or set the value in A1. The practical choice is about how you want to identify the target: with a readable address, or with row and column numbers.
What Range and Cells mean
Range is a property of a worksheet that identifies one or more cells by an address or range reference. In VBA, the expression is usually qualified with the worksheet you intend to use, such as ws.Range("B2:D5"). This returns a Range object, which can expose properties such as Value, Address, and Font, and methods such as ClearContents or Copy.
Cells identifies cells by row and column numbers. On a worksheet, ws.Cells(1, 1) means A1, and ws.Cells(3, 2) means B3. The first argument is the row number; the second is the column number. Because the result is still a Range object, you can write ws.Cells(3, 2).Value or assign it to a variable declared As Range.
Both are ways to refer to worksheet cells, not competing data types. Also, VBA’s Cells property is not the same thing as an Excel worksheet formula or a special object called “Cell.” If you see a variable declared as Dim target As Range, that variable can hold a reference to one cell or many.
Syntax and concrete examples
Use a worksheet variable to make the target unambiguous. The following macro prints the addresses of one cell and a block to the Immediate window in the Visual Basic Editor. Change Sheet1 if your workbook uses a different worksheet name. It only prints addresses, but save a copy of the workbook before running macros; changes made by VBA cannot be undone with Ctrl+Z.
Sub CompareAddresses()
Dim ws As Worksheet
Dim oneCell As Range
Dim block As Range
' Replace Sheet1 with the worksheet name in your workbook.
Set ws = ThisWorkbook.Worksheets("Sheet1")
Set oneCell = ws.Range("B3")
Set block = ws.Range("B2:D5")
Debug.Print oneCell.Address
Debug.Print block.Address
End Sub
For a single cell, these two expressions refer to the same location: ws.Range("B3") and ws.Cells(3, 2). For a block whose boundaries are known as numbers, combine Cells with Range: ws.Range(ws.Cells(2, 2), ws.Cells(5, 4)) describes B2:D5. The two Cells expressions provide the top-left and bottom-right corners.
That combination is useful when the row numbers come from a calculation or variable. It avoids building an address string manually and makes the intended row and column logic visible. In contrast, ws.Range("B2:D5") is often easier to scan when the address is fixed and familiar to the person maintaining the code.
When to choose Range or Cells
Choose the form that best fits how the address is known. A clear address is usually easiest for a fixed target; numeric indexing is usually easier for a target that changes as a loop runs or depends on a calculated position.
- Use Range for fixed, readable addresses:
ws.Range("A1"),ws.Range("A1:C10"), orws.Range("SalesTotal")when a workbook-level or worksheet-level named range exists. - Use Cells for variable positions:
ws.Cells(rowNum, 4)clearly means column D on a row selected byrowNum. - Use both for a calculated rectangle: pass two Cells references as the start and end points of a Range.
- Use a Range variable when you reuse a target: setting it once can make longer procedures easier to read and maintain.
For example, when a procedure must process rows 2 through 5 and place twice the value from column A into column B, the row number varies but the column numbers stay fixed. The macro below illustrates that pattern. It assumes A2:A5 contain numbers and that overwriting B2:B5 is acceptable. Save a copy before running it because the writes cannot be reversed with Ctrl+Z.
Sub FillDoubledValues()
Dim ws As Worksheet
Dim rowNum As Long
' Replace Sheet1 with the worksheet name in your workbook.
Set ws = ThisWorkbook.Worksheets("Sheet1")
For rowNum = 2 To 5
ws.Cells(rowNum, 2).Value = ws.Cells(rowNum, 1).Value * 2
Next rowNum
End Sub
Indexing, relative references, and worksheet qualification
On a worksheet, ws.Cells(row, column) counts from the top-left of the worksheet: row 1, column 1 is A1. The row and column arguments are numbers, so a column number of 27 refers to column AA. This can be convenient when a macro discovers a column position dynamically rather than knowing its letter in advance.
Cells can also be called from a Range object. In that case, the row and column indexes are relative to that Range’s top-left cell. For example, ws.Range("B2").Cells(1, 1) refers to B2, and ws.Range("B2").Cells(2, 3) refers to D3. This relative behavior is useful for working inside a known block, but it can confuse readers who assume those indexes always mean worksheet row 1 and column 1.
Qualifying a reference with its worksheet is a strong habit. An unqualified Range("A1") or Cells(1, 1) generally refers to the active sheet, which can change when a user clicks another tab or when code activates a different sheet. A reference such as ThisWorkbook.Worksheets("Sheet1").Range("A1") makes the target explicit. ThisWorkbook means the workbook containing the VBA code; it differs from ActiveWorkbook, which means the workbook currently active in Excel.
Reading and changing cell values
Once you have a Range reference, use its properties to read or change worksheet content. Value is commonly used for cell values. Value2 is also available and returns or sets values without using the Currency and Date subtypes that Value may use; Excel date and currency values can therefore be represented as numbers. For straightforward examples, either property can be appropriate, but code that depends on date or currency interpretation should choose deliberately.
A single-cell reference returns a single value. A reference to a multi-cell block can return a two-dimensional array when read through Value or Value2. That means a variable receiving an entire block may need to be declared as a Variant, rather than a single string or number. Assigning a suitably sized two-dimensional array to a rectangular Range can write many cells in one operation. This is often more efficient than reading or writing each cell separately in a large loop.
Be careful with properties and methods that affect the whole referenced range. For example, block.ClearContents removes values and formulas from every cell in the block but leaves formatting in place. Assigning one value to a multi-cell Range generally applies that value across the referenced cells. If you intend to change only one cell, make sure the target is a single-cell reference rather than a broad range.
Common mistakes and how to avoid them
Many problems attributed to “Range versus Cells” are actually issues with scope, object assignment, or the size of the target. Keep these points in mind when writing or debugging VBA:
- Forgetting
Setfor object variables: useSet target = ws.Cells(1, 1)when assigning a Range object to a variable declaredAs Range.Setis not used when assigning a cell’s value, such astarget.Value = 10. - Relying on the active sheet: qualify
RangeandCellswith a worksheet variable instead of assuming the correct tab is active. - Mixing up row and column order:
Cells(3, 2)is B3, not C2. The first number is the row. - Using Cells as a range address string:
Cells(rowNum, colNum)returns a Range object; it is not a string like"B3". Use.Addressif you specifically need its address text. - Writing into data unintentionally: a macro can overwrite formulas or values without a confirmation prompt. Check the worksheet and the exact target before running it.
- Expecting Ctrl+Z to reverse VBA: running a macro clears Excel’s ordinary undo history. Save a copy before running code that changes workbook contents.
Speed, selection, and safer macro habits
Using Range instead of Cells, or vice versa, does not by itself make a macro faster. They both identify Range objects. Performance depends more on how often code reads from or writes to the worksheet and whether it makes unnecessary selections. For large blocks, reading a block into an array, processing the values in memory, and writing the result back in one assignment can reduce repeated communication with the worksheet.
Most procedures do not need to select a cell first. For example, ws.Range("A1").Value = "Done" addresses the target directly. Calling Select first usually adds a dependency on which sheet is active and can make automation more fragile. Selection is appropriate when a macro is deliberately guiding a user’s view, but it is not required simply to edit or inspect a cell.
For Windows, Alt+F11 opens the Visual Basic Editor in Excel. On Mac, Option+F11 is commonly used, though some keyboards require holding Fn as well; the Developer tab’s Visual Basic command is another route. Excel for the web can open and edit workbooks that contain VBA, but it cannot create, run, or edit VBA macros. Use the desktop Excel application for these examples.
Frequently Asked Questions
Is Cells better than Range in VBA?
Neither is universally better. Use Range when an address is fixed and readability matters; use Cells when row or column numbers are calculated or change in a loop. Both return Range objects for worksheet cells.
Does Cells(1, 1) mean A1?
Yes, when used on a worksheet, the first argument is the row and the second is the column, so Cells(1, 1) refers to A1. Qualify it with a worksheet, such as ws.Cells(1, 1), to avoid relying on the active sheet.
Can Range refer to only one cell?
Yes. Range("A1") is a Range object representing one cell. Range objects can also represent multiple cells, whole rows or columns, and named ranges.
What is the difference between Cells and Range in a loop?Cells(rowNum, columnNum) naturally uses numeric variables for changing positions. Range can still be used in a loop, but constructing address strings is often less direct. For a changing rectangular block, use Range with two calculated Cells references.
Why does Range(“A1”) sometimes change the wrong sheet?
An unqualified Range reference uses the active sheet context. If another sheet is active, the reference may point there. Store the intended worksheet in a variable and use ws.Range("A1") or ws.Cells(1, 1).
Related
- Excel Slicer Tutorial: Add, Format, and Connect Filters
- Excel Slicer Search Box: How to Find Items
- Excel Slicer Examples for PivotTables and Tables Explained
Try it: the Column Letter to Number: aA is 27, XFD is 16,384. Converts both ways.
More in VBA & macros
- Gamepad Macro Recorder: How It Works and What to KnowA gamepad macro recorder captures a sequence of controller inputs—such as button presses, stick movements, and pauses—and plays…
- Optimize Copy Paste VBA for Faster Excel WorkbooksTo optimize copy-and-paste in Excel VBA, avoid selecting cells and using the clipboard when you only need to…
- VBA Copy and Paste Excel Cells Into the Email BodyYes. In Excel for Microsoft 365 on Windows, VBA can copy a cell range and paste it into…
- Excel VBA: Copy and Paste Values Without FormulasTo copy a range’s results without its formulas in Excel VBA, copy the source range and use PasteSpecial…
- VBA MsgBox Font Size: What You Can and Cannot ChangeYou cannot set the font size of VBA’s built-in MsgBox in Excel: the function has no font-size argument…
- Excel VBA Pivot Charts: How to Create and Refresh ThemYes—VBA can refresh, filter, and manage Excel PivotCharts, and you can create one by selecting a PivotTable and…
Sources: Function behaviour and menu paths: Microsoft Support documentation for Excel. Method & sources
Spotted an error in this guide? Let us know.