Vba excel range object methods

title keywords f1_keywords ms.prod api_name ms.assetid ms.date ms.localizationpriority

Range object (Excel)

vbaxl10.chm143072

vbaxl10.chm143072

excel

Excel.Range

b8207778-0dcc-4570-1234-f130532cc8cd

08/14/2019

high

Range object (Excel)

Represents a cell, a row, a column, a selection of cells containing one or more contiguous blocks of cells, or a 3D range.

[!includeAdd-ins note]

Remarks

The default member of Range forwards calls without parameters to the Value property and calls with parameters to the Item member. Accordingly, someRange = someOtherRange is equivalent to someRange.Value = someOtherRange.Value, someRange(1) to someRange.Item(1) and someRange(1,1) to someRange.Item(1,1).

The following properties and methods for returning a Range object are described in the Example section:

  • Range and Cells properties of the Worksheet object
  • Range and Cells properties of the Range object
  • Rows and Columns properties of the Worksheet object
  • Rows and Columns properties of the Range object
  • Offset property of the Range object
  • Union method of the Application object

Example

Use Range (arg), where arg names the range, to return a Range object that represents a single cell or a range of cells. The following example places the value of cell A1 in cell A5.

Worksheets("Sheet1").Range("A5").Value = _ 
    Worksheets("Sheet1").Range("A1").Value

The following example fills the range A1:H8 with random numbers by setting the formula for each cell in the range. When it’s used without an object qualifier (an object to the left of the period), the Range property returns a range on the active sheet. If the active sheet isn’t a worksheet, the method fails.

Use the Activate method of the Worksheet object to activate a worksheet before you use the Range property without an explicit object qualifier.

Worksheets("Sheet1").Activate 
Range("A1:H8").Formula = "=Rand()"    'Range is on the active sheet

The following example clears the contents of the range named Criteria.

[!NOTE]
If you use a text argument for the range address, you must specify the address in A1-style notation (you cannot use R1C1-style notation).

Worksheets(1).Range("Criteria").ClearContents

Use Cells on a worksheet to obtain a range consisting all single cells on the worksheet. You can access single cells via Item(row, column), where row is the row index and column is the column index.
Item can be omitted since the call is forwarded to it by the default member of Range.
The following example sets the value of cell A1 to 24 and of cell B1 to 42 on the first sheet of the active workbook.

Worksheets(1).Cells(1, 1).Value = 24
Worksheets(1).Cells.Item(1, 2).Value = 42

The following example sets the formula for cell A2.

ActiveSheet.Cells(2, 1).Formula = "=Sum(B1:B5)"

Although you can also use Range("A1") to return cell A1, there may be times when the Cells property is more convenient because you can use a variable for the row or column. The following example creates column and row headings on Sheet1. Be aware that after the worksheet has been activated, the Cells property can be used without an explicit sheet declaration (it returns a cell on the active sheet).

[!NOTE]
Although you could use Visual Basic string functions to alter A1-style references, it is easier (and better programming practice) to use the Cells(1, 1) notation.

Sub SetUpTable() 
Worksheets("Sheet1").Activate 
For TheYear = 1 To 5 
    Cells(1, TheYear + 1).Value = 1990 + TheYear 
Next TheYear 
For TheQuarter = 1 To 4 
    Cells(TheQuarter + 1, 1).Value = "Q" & TheQuarter 
Next TheQuarter 
End Sub

Use_expression_.Cells, where expression is an expression that returns a Range object, to obtain a range with the same address consisting of single cells.
On such a range, you access single cells via Item(row, column), where are relative to the upper-left corner of the first area of the range.
Item can be omitted since the call is forwarded to it by the default member of Range.
The following example sets the formula for cell C5 and D5 of the first sheet of the active workbook.

Worksheets(1).Range("C5:C10").Cells(1, 1).Formula = "=Rand()"
Worksheets(1).Range("C5:C10").Cells.Item(1, 2).Formula = "=Rand()"

Use Range (cell1, cell2), where cell1 and cell2 are Range objects that specify the start and end cells, to return a Range object. The following example sets the border line style for cells A1:J10.

[!NOTE]
Be aware that the period in front of each occurrence of the Cells property is required if the result of the preceding With statement is to be applied to the Cells property. In this case, it indicates that the cells are on worksheet one (without the period, the Cells property would return cells on the active sheet).

With Worksheets(1) 
    .Range(.Cells(1, 1), _ 
        .Cells(10, 10)).Borders.LineStyle = xlThick 
End With

Use Rows on a worksheet to obtain a range consisting all rows on the worksheet. You can access single rows via Item(row), where row is the row index.
Item can be omitted since the call is forwarded to it by the default member of Range.

[!NOTE]
It’s not legal to provide the second parameter of Item for ranges consisting of rows. You first have to convert it to single cells via Cells.

The following example deletes row 5 and 10 of the first sheet of the active workbook.

Worksheets(1).Rows(10).Delete
Worksheets(1).Rows.Item(5).Delete

Use Columns on a worksheet to obtain a range consisting all columns on the worksheet. You can access single columns via Item(row) [sic], where row is the column index given as a number or as an A1-style column address.
Item can be omitted since the call is forwarded to it by the default member of Range.

[!NOTE]
It’s not legal to provide the second parameter of Item for ranges consisting of columns. You first have to convert it to single cells via Cells.

The following example deletes column «B», «C», «E», and «J» of the first sheet of the active workbook.

Worksheets(1).Columns(10).Delete
Worksheets(1).Columns.Item(5).Delete
Worksheets(1).Columns("C").Delete
Worksheets(1).Columns.Item("B").Delete

Use_expression_.Rows, where expression is an expression that returns a Range object, to obtain a range consisting of the rows in the first area of the range.
You can access single rows via Item(row), where row is the relative row index from the top of the first area of the range.
Item can be omitted since the call is forwarded to it by the default member of Range.

[!NOTE]
It’s not legal to provide the second parameter of Item for ranges consisting of rows. You first have to convert it to single cells via Cells.

The following example deletes the ranges C8:D8 and C6:D6 of the first sheet of the active workbook.

Worksheets(1).Range("C5:D10").Rows(4).Delete
Worksheets(1).Range("C5:D10").Rows.Item(2).Delete

Use_expression_.Columns, where expression is an expression that returns a Range object, to obtain a range consisting of the columns in the first area of the range.
You can access single columns via Item(row) [sic], where row is the relative column index from the left of the first area of the range given as a number or as an A1-style column address.
Item can be omitted since the call is forwarded to it by the default member of Range.

[!NOTE]
It’s not legal to provide the second parameter of Item for ranges consisting of columns. You first have to convert it to single cells via Cells.

The following example deletes the ranges L2:L10, G2:G10, F2:F10 and D2:D10 of the first sheet of the active workbook.

Worksheets(1).Range("C5:Z10").Columns(10).Delete
Worksheets(1).Range("C5:Z10").Columns.Item(5).Delete
Worksheets(1).Range("C5:Z10").Columns("D").Delete
Worksheets(1).Range("C5:Z10").Columns.Item("B").Delete

Use Offset (row, column), where row and column are the row and column offsets, to return a range at a specified offset to another range. The following example selects the cell three rows down from and one column to the right of the cell in the upper-left corner of the current selection. You cannot select a cell that is not on the active sheet, so you must first activate the worksheet.

Worksheets("Sheet1").Activate 
  'Can't select unless the sheet is active 
Selection.Offset(3, 1).Range("A1").Select

Use Union (range1, range2, …) to return multiple-area ranges—that is, ranges composed of two or more contiguous blocks of cells. The following example creates an object defined as the union of ranges A1:B2 and C3:D4, and then selects the defined range.

Dim r1 As Range, r2 As Range, myMultiAreaRange As Range 
Worksheets("sheet1").Activate 
Set r1 = Range("A1:B2") 
Set r2 = Range("C3:D4") 
Set myMultiAreaRange = Union(r1, r2) 
myMultiAreaRange.Select

If you work with selections that contain more than one area, the Areas property is useful. It divides a multiple-area selection into individual Range objects and then returns the objects as a collection. Use the Count property on the returned collection to verify a selection that contains more than one area, as shown in the following example.

Sub NoMultiAreaSelection() 
    NumberOfSelectedAreas = Selection.Areas.Count 
    If NumberOfSelectedAreas > 1 Then 
        MsgBox "You cannot carry out this command " & _ 
            "on multi-area selections" 
    End If 
End Sub

This example uses the AdvancedFilter method of the Range object to create a list of the unique values, and the number of times those unique values occur, in the range of column A.

Sub Create_Unique_List_Count()
    'Excel workbook, the source and target worksheets, and the source and target ranges.
    Dim wbBook As Workbook
    Dim wsSource As Worksheet
    Dim wsTarget As Worksheet
    Dim rnSource As Range
    Dim rnTarget As Range
    Dim rnUnique As Range
    'Variant to hold the unique data
    Dim vaUnique As Variant
    'Number of unique values in the data
    Dim lnCount As Long
    
    'Initialize the Excel objects
    Set wbBook = ThisWorkbook
    With wbBook
        Set wsSource = .Worksheets("Sheet1")
        Set wsTarget = .Worksheets("Sheet2")
    End With
    
    'On the source worksheet, set the range to the data stored in column A
    With wsSource
        Set rnSource = .Range(.Range("A1"), .Range("A100").End(xlDown))
    End With
    
    'On the target worksheet, set the range as column A.
    Set rnTarget = wsTarget.Range("A1")
    
    'Use AdvancedFilter to copy the data from the source to the target,
    'while filtering for duplicate values.
    rnSource.AdvancedFilter Action:=xlFilterCopy, _
                            CopyToRange:=rnTarget, _
                            Unique:=True
                            
    'On the target worksheet, set the unique range on Column A, excluding the first cell
    '(which will contain the "List" header for the column).
    With wsTarget
        Set rnUnique = .Range(.Range("A2"), .Range("A100").End(xlUp))
    End With
    
    'Assign all the values of the Unique range into the Unique variant.
    vaUnique = rnUnique.Value
    
    'Count the number of occurrences of every unique value in the source data,
    'and list it next to its relevant value.
    For lnCount = 1 To UBound(vaUnique)
        rnUnique(lnCount, 1).Offset(0, 1).Value = _
            Application.Evaluate("COUNTIF(" & _
            rnSource.Address(External:=True) & _
            ",""" & rnUnique(lnCount, 1).Text & """)")
    Next lnCount
    
    'Label the column of occurrences with "Occurrences"
    With rnTarget.Offset(0, 1)
        .Value = "Occurrences"
        .Font.Bold = True
    End With

End Sub

Methods

  • Activate
  • AddComment
  • AddCommentThreaded
  • AdvancedFilter
  • AllocateChanges
  • ApplyNames
  • ApplyOutlineStyles
  • AutoComplete
  • AutoFill
  • AutoFilter
  • AutoFit
  • AutoOutline
  • BorderAround
  • Calculate
  • CalculateRowMajorOrder
  • CheckSpelling
  • Clear
  • ClearComments
  • ClearContents
  • ClearFormats
  • ClearHyperlinks
  • ClearNotes
  • ClearOutline
  • ColumnDifferences
  • Consolidate
  • ConvertToLinkedDataType
  • Copy
  • CopyFromRecordset
  • CopyPicture
  • CreateNames
  • Cut
  • DataTypeToText
  • DataSeries
  • Delete
  • DialogBox
  • Dirty
  • DiscardChanges
  • EditionOptions
  • ExportAsFixedFormat
  • FillDown
  • FillLeft
  • FillRight
  • FillUp
  • Find
  • FindNext
  • FindPrevious
  • FlashFill
  • FunctionWizard
  • Group
  • Insert
  • InsertIndent
  • Justify
  • ListNames
  • Merge
  • NavigateArrow
  • NoteText
  • Parse
  • PasteSpecial
  • PrintOut
  • PrintPreview
  • RemoveDuplicates
  • RemoveSubtotal
  • Replace
  • RowDifferences
  • Run
  • Select
  • SetCellDataTypeFromCell
  • SetPhonetic
  • Show
  • ShowCard
  • ShowDependents
  • ShowErrors
  • ShowPrecedents
  • Sort
  • SortSpecial
  • Speak
  • SpecialCells
  • SubscribeTo
  • Subtotal
  • Table
  • TextToColumns
  • Ungroup
  • UnMerge

Properties

  • AddIndent
  • Address
  • AddressLocal
  • AllowEdit
  • Application
  • Areas
  • Borders
  • Cells
  • Characters
  • Column
  • Columns
  • ColumnWidth
  • Comment
  • CommentThreaded
  • Count
  • CountLarge
  • Creator
  • CurrentArray
  • CurrentRegion
  • Dependents
  • DirectDependents
  • DirectPrecedents
  • DisplayFormat
  • End
  • EntireColumn
  • EntireRow
  • Errors
  • Font
  • FormatConditions
  • Formula
  • FormulaArray
  • FormulaHidden
  • FormulaLocal
  • FormulaR1C1
  • FormulaR1C1Local
  • HasArray
  • HasFormula
  • HasRichDataType
  • Height
  • Hidden
  • HorizontalAlignment
  • Hyperlinks
  • ID
  • IndentLevel
  • Interior
  • Item
  • Left
  • LinkedDataTypeState
  • ListHeaderRows
  • ListObject
  • LocationInTable
  • Locked
  • MDX
  • MergeArea
  • MergeCells
  • Name
  • Next
  • NumberFormat
  • NumberFormatLocal
  • Offset
  • Orientation
  • OutlineLevel
  • PageBreak
  • Parent
  • Phonetic
  • Phonetics
  • PivotCell
  • PivotField
  • PivotItem
  • PivotTable
  • Precedents
  • PrefixCharacter
  • Previous
  • QueryTable
  • Range
  • ReadingOrder
  • Resize
  • Row
  • RowHeight
  • Rows
  • ServerActions
  • ShowDetail
  • ShrinkToFit
  • SoundNote
  • SparklineGroups
  • Style
  • Summary
  • Text
  • Top
  • UseStandardHeight
  • UseStandardWidth
  • Validation
  • Value
  • Value2
  • VerticalAlignment
  • Width
  • Worksheet
  • WrapText
  • XPath

See also

  • Excel Object Model Reference

[!includeSupport and feedback]

“It is a capital mistake to theorize before one has data”- Sir Arthur Conan Doyle

This post covers everything you need to know about using Cells and Ranges in VBA. You can read it from start to finish as it is laid out in a logical order. If you prefer you can use the table of contents below to go to a section of your choice.

Topics covered include Offset property, reading values between cells, reading values to arrays and formatting cells.

A Quick Guide to Ranges and Cells

Function Takes Returns Example Gives

Range

cell address multiple cells .Range(«A1:A4») $A$1:$A$4
Cells row, column one cell .Cells(1,5) $E$1
Offset row, column multiple cells Range(«A1:A2»)
.Offset(1,2)
$C$2:$C$3
Rows row(s) one or more rows .Rows(4)
.Rows(«2:4»)
$4:$4
$2:$4
Columns column(s) one or more columns .Columns(4)
.Columns(«B:D»)
$D:$D
$B:$D

Download the Code

 

The Webinar

If you are a member of the VBA Vault, then click on the image below to access the webinar and the associated source code.

(Note: Website members have access to the full webinar archive.)

vba ranges video

Introduction

This is the third post dealing with the three main elements of VBA. These three elements are the Workbooks, Worksheets and Ranges/Cells. Cells are by far the most important part of Excel. Almost everything you do in Excel starts and ends with Cells.

 
Generally speaking, you do three main things with Cells

  1. Read from a cell.
  2. Write to a cell.
  3. Change the format of a cell.

 
Excel has a number of methods for accessing cells such as Range, Cells and Offset.These can cause confusion as they do similar things and can lead to confusion

In this post I will tackle each one, explain why you need it and when you should use it.

 
Let’s start with the simplest method of accessing cells – using the Range property of the worksheet.

Important Notes

I have recently updated this article so that is uses Value2.

You may be wondering what is the difference between Value, Value2 and the default:

' Value2
Range("A1").Value2 = 56

' Value
Range("A1").Value = 56

' Default uses value
Range("A1") = 56

 
Using Value may truncate number if the cell is formatted as currency. If you don’t use any property then the default is Value.

It is better to use Value2 as it will always return the actual cell value(see this article from Charle Williams.)

The Range Property

The worksheet has a Range property which you can use to access cells in VBA. The Range property takes the same argument that most Excel Worksheet functions take e.g. “A1”, “A3:C6” etc.

The following example shows you how to place a value in a cell using the Range property.

' https://excelmacromastery.com/
Public Sub WriteToCell()

    ' Write number to cell A1 in sheet1 of this workbook
    ThisWorkbook.Worksheets("Sheet1").Range("A1").Value2 = 67

    ' Write text to cell A2 in sheet1 of this workbook
    ThisWorkbook.Worksheets("Sheet1").Range("A2").Value2 = "John Smith"

    ' Write date to cell A3 in sheet1 of this workbook
    ThisWorkbook.Worksheets("Sheet1").Range("A3").Value2 = #11/21/2017#

End Sub

 
As you can see Range is a member of the worksheet which in turn is a member of the Workbook. This follows the same hierarchy as in Excel so should be easy to understand. To do something with Range you must first specify the workbook and worksheet it belongs to.

For the rest of this post I will use the code name to reference the worksheet.

code name worksheet

 
 
The following code shows the above example using the code name of the worksheet i.e. Sheet1 instead of ThisWorkbook.Worksheets(“Sheet1”).

' https://excelmacromastery.com/
Public Sub UsingCodeName()

    ' Write number to cell A1 in sheet1 of this workbook
    Sheet1.Range("A1").Value2 = 67

    ' Write text to cell A2 in sheet1 of this workbook
    Sheet1.Range("A2").Value2 = "John Smith"

    ' Write date to cell A3 in sheet1 of this workbook
    Sheet1.Range("A3").Value2 = #11/21/2017#

End Sub

You can also write to multiple cells using the Range property

' https://excelmacromastery.com/
Public Sub WriteToMulti()

    ' Write number to a range of cells
    Sheet1.Range("A1:A10").Value2 = 67

    ' Write text to multiple ranges of cells
    Sheet1.Range("B2:B5,B7:B9").Value2 = "John Smith"

End Sub

 
You can download working examples of all the code from this post from the top of this article.
 

The Cells Property of the Worksheet

The worksheet object has another property called Cells which is very similar to range. There are two differences

  1. Cells returns a range of one cell only.
  2. Cells takes row and column as arguments.

 
The example below shows you how to write values to cells using both the Range and Cells property

' https://excelmacromastery.com/
Public Sub UsingCells()

    ' Write to A1
    Sheet1.Range("A1").Value2 = 10
    Sheet1.Cells(1, 1).Value2  = 10

    ' Write to A10
    Sheet1.Range("A10").Value2 = 10
    Sheet1.Cells(10, 1).Value2  = 10

    ' Write to E1
    Sheet1.Range("E1").Value2 = 10
    Sheet1.Cells(1, 5).Value2  = 10

End Sub

 
You may be wondering when you should use Cells and when you should use Range. Using Range is useful for accessing the same cells each time the Macro runs.

For example, if you were using a Macro to calculate a total and write it to cell A10 every time then Range would be suitable for this task.

Using the Cells property is useful if you are accessing a cell based on a number that may vary. It is easier to explain this with an example.

 
In the following code, we ask the user to specify the column number. Using Cells gives us the flexibility to use a variable number for the column.

' https://excelmacromastery.com/
Public Sub WriteToColumn()

    Dim UserCol As Integer
    
    ' Get the column number from the user
    UserCol = Application.InputBox(" Please enter the column...", Type:=1)
    
    ' Write text to user selected column
    Sheet1.Cells(1, UserCol).Value2 = "John Smith"

End Sub

 
In the above example, we are using a number for the column rather than a letter.

To use Range here would require us to convert these values to the letter/number  cell reference e.g. “C1”. Using the Cells property allows us to provide a row and a column number to access a cell.

Sometimes you may want to return more than one cell using row and column numbers. The next section shows you how to do this.

Using Cells and Range together

As you have seen you can only access one cell using the Cells property. If you want to return a range of cells then you can use Cells with Ranges as follows

' https://excelmacromastery.com/
Public Sub UsingCellsWithRange()

    With Sheet1
        ' Write 5 to Range A1:A10 using Cells property
        .Range(.Cells(1, 1), .Cells(10, 1)).Value2 = 5

        ' Format Range B1:Z1 to be bold
        .Range(.Cells(1, 2), .Cells(1, 26)).Font.Bold = True

    End With

End Sub

 
As you can see, you provide the start and end cell of the Range. Sometimes it can be tricky to see which range you are dealing with when the value are all numbers. Range has a property called Address which displays the letter/ number cell reference of any range. This can come in very handy when you are debugging or writing code for the first time.

 
In the following example we print out the address of the ranges we are using:

' https://excelmacromastery.com/
Public Sub ShowRangeAddress()

    ' Note: Using underscore allows you to split up lines of code
    With Sheet1

        ' Write 5 to Range A1:A10 using Cells property
        .Range(.Cells(1, 1), .Cells(10, 1)).Value2 = 5
        Debug.Print "First address is : " _
            + .Range(.Cells(1, 1), .Cells(10, 1)).Address

        ' Format Range B1:Z1 to be bold
        .Range(.Cells(1, 2), .Cells(1, 26)).Font.Bold = True
        Debug.Print "Second address is : " _
            + .Range(.Cells(1, 2), .Cells(1, 26)).Address

    End With

End Sub

 
In the example I used Debug.Print to print to the Immediate Window. To view this window select View->Immediate Window(or Ctrl G)

 
ImmediateWindow

 
ImmediateSampeText

 
You can download all the code for this post from the top of this article.
 

The Offset Property of Range

Range has a property called Offset. The term Offset refers to a count from the original position. It is used a lot in certain areas of programming. With the Offset property you can get a Range of cells the same size and a certain distance from the current range. The reason this is useful is that sometimes you may want to select a Range based on a certain condition. For example in the screenshot below there is a column for each day of the week. Given the day number(i.e. Monday=1, Tuesday=2 etc.) we need to write the value to the correct column.

 
VBA Offset

 
We will first attempt to do this without using Offset.

' https://excelmacromastery.com/
' This sub tests with different values
Public Sub TestSelect()

    ' Monday
    SetValueSelect 1, 111.21
    ' Wednesday
    SetValueSelect 3, 456.99
    ' Friday
    SetValueSelect 5, 432.25
    ' Sunday
    SetValueSelect 7, 710.17

End Sub

' Writes the value to a column based on the day
Public Sub SetValueSelect(lDay As Long, lValue As Currency)

    Select Case lDay
        Case 1: Sheet1.Range("H3").Value2 = lValue
        Case 2: Sheet1.Range("I3").Value2 = lValue
        Case 3: Sheet1.Range("J3").Value2 = lValue
        Case 4: Sheet1.Range("K3").Value2 = lValue
        Case 5: Sheet1.Range("L3").Value2 = lValue
        Case 6: Sheet1.Range("M3").Value2 = lValue
        Case 7: Sheet1.Range("N3").Value2 = lValue
    End Select

End Sub

 
As you can see in the example, we need to add a line for each possible option. This is not an ideal situation. Using the Offset Property provides a much cleaner solution

' https://excelmacromastery.com/
' This sub tests with different values
Public Sub TestOffset()

    DayOffSet 1, 111.01
    DayOffSet 3, 456.99
    DayOffSet 5, 432.25
    DayOffSet 7, 710.17

End Sub

Public Sub DayOffSet(lDay As Long, lValue As Currency)

    ' We use the day value with offset specify the correct column
    Sheet1.Range("G3").Offset(, lDay).Value2 = lValue

End Sub

 
As you can see this solution is much better. If the number of days in increased then we do not need to add any more code. For Offset to be useful there needs to be some kind of relationship between the positions of the cells. If the Day columns in the above example were random then we could not use Offset. We would have to use the first solution.

 
One thing to keep in mind is that Offset retains the size of the range. So .Range(“A1:A3”).Offset(1,1) returns the range B2:B4. Below are some more examples of using Offset

' https://excelmacromastery.com/
Public Sub UsingOffset()

    ' Write to B2 - no offset
    Sheet1.Range("B2").Offset().Value2 = "Cell B2"

    ' Write to C2 - 1 column to the right
    Sheet1.Range("B2").Offset(, 1).Value2 = "Cell C2"

    ' Write to B3 - 1 row down
    Sheet1.Range("B2").Offset(1).Value2 = "Cell B3"

    ' Write to C3 - 1 column right and 1 row down
    Sheet1.Range("B2").Offset(1, 1).Value2 = "Cell C3"

    ' Write to A1 - 1 column left and 1 row up
    Sheet1.Range("B2").Offset(-1, -1).Value2 = "Cell A1"

    ' Write to range E3:G13 - 1 column right and 1 row down
    Sheet1.Range("D2:F12").Offset(1, 1).Value2 = "Cells E3:G13"

End Sub

Using the Range CurrentRegion

CurrentRegion returns a range of all the adjacent cells to the given range.

In the screenshot below you can see the two current regions. I have added borders to make the current regions clear.

VBA CurrentRegion

A row or column of blank cells signifies the end of a current region.

You can manually check the CurrentRegion in Excel by selecting a range and pressing Ctrl + Shift + *.

If we take any range of cells within the border and apply CurrentRegion, we will get back the range of cells in the entire area.

For example
Range(“B3”).CurrentRegion will return the range B3:D14
Range(“D14”).CurrentRegion will return the range B3:D14
Range(“C8:C9”).CurrentRegion will return the range B3:D14
and so on

How to Use

We get the CurrentRegion as follows

' Current region will return B3:D14 from above example
Dim rg As Range
Set rg = Sheet1.Range("B3").CurrentRegion

Read Data Rows Only

Read through the range from the second row i.e.skipping the header row

' Current region will return B3:D14 from above example
Dim rg As Range
Set rg = Sheet1.Range("B3").CurrentRegion

' Start at row 2 - row after header
Dim i As Long
For i = 2 To rg.Rows.Count
    ' current row, column 1 of range
    Debug.Print rg.Cells(i, 1).Value2
Next i

Remove Header

Remove header row(i.e. first row) from the range. For example if range is A1:D4 this will return A2:D4

' Current region will return B3:D14 from above example
Dim rg As Range
Set rg = Sheet1.Range("B3").CurrentRegion

' Remove Header
Set rg = rg.Resize(rg.Rows.Count - 1).Offset(1)

' Start at row 1 as no header row
Dim i As Long
For i = 1 To rg.Rows.Count
    ' current row, column 1 of range
    Debug.Print rg.Cells(i, 1).Value2
Next i

 

Using Rows and Columns as Ranges

If you want to do something with an entire Row or Column you can use the Rows or Columns property of the Worksheet. They both take one parameter which is the row or column number you wish to access

' https://excelmacromastery.com/
Public Sub UseRowAndColumns()

    ' Set the font size of column B to 9
    Sheet1.Columns(2).Font.Size = 9

    ' Set the width of columns D to F
    Sheet1.Columns("D:F").ColumnWidth = 4

    ' Set the font size of row 5 to 18
    Sheet1.Rows(5).Font.Size = 18

End Sub

Using Range in place of Worksheet

You can also use Cells, Rows and Columns as part of a Range rather than part of a Worksheet. You may have a specific need to do this but otherwise I would avoid the practice. It makes the code more complex. Simple code is your friend. It reduces the possibility of errors.

 
The code below will set the second column of the range to bold. As the range has only two rows the entire column is considered B1:B2

' https://excelmacromastery.com/
Public Sub UseColumnsInRange()

    ' This will set B1 and B2 to be bold
    Sheet1.Range("A1:C2").Columns(2).Font.Bold = True

End Sub

 
You can download all the code for this post from the top of this article.
 

Reading Values from one Cell to another

In most of the examples so far we have written values to a cell. We do this by placing the range on the left of the equals sign and the value to place in the cell on the right. To write data from one cell to another we do the same. The destination range goes on the left and the source range goes on the right.

 
The following example shows you how to do this:

' https://excelmacromastery.com/
Public Sub ReadValues()

    ' Place value from B1 in A1
    Sheet1.Range("A1").Value2 = Sheet1.Range("B1").Value2

    ' Place value from B3 in sheet2 to cell A1
    Sheet1.Range("A1").Value2 = Sheet2.Range("B3").Value2

    ' Place value from B1 in cells A1 to A5
    Sheet1.Range("A1:A5").Value2 = Sheet1.Range("B1").Value2

    ' You need to use the "Value" property to read multiple cells
    Sheet1.Range("A1:A5").Value2 = Sheet1.Range("B1:B5").Value2

End Sub

 
As you can see from this example it is not possible to read from multiple cells. If you want to do this you can use the Copy function of Range with the Destination parameter

' https://excelmacromastery.com/
Public Sub CopyValues()

    ' Store the copy range in a variable
    Dim rgCopy As Range
    Set rgCopy = Sheet1.Range("B1:B5")

    ' Use this to copy from more than one cell
    rgCopy.Copy Destination:=Sheet1.Range("A1:A5")

    ' You can paste to multiple destinations
    rgCopy.Copy Destination:=Sheet1.Range("A1:A5,C2:C6")

End Sub

 
The Copy function copies everything including the format of the cells. It is the same result as manually copying and pasting a selection. You can see more about it in the Copying and Pasting Cells section.

Using the Range.Resize Method

When copying from one range to another using assignment(i.e. the equals sign), the destination range must be the same size as the source range.

Using the Resize function allows us to resize a range to a given number of rows and columns.

For example:
 

' https://excelmacromastery.com/
Sub ResizeExamples()
 
    ' Prints A1
    Debug.Print Sheet1.Range("A1").Address

    ' Prints A1:A2
    Debug.Print Sheet1.Range("A1").Resize(2, 1).Address

    ' Prints A1:A5
    Debug.Print Sheet1.Range("A1").Resize(5, 1).Address
    
    ' Prints A1:D1
    Debug.Print Sheet1.Range("A1").Resize(1, 4).Address
    
    ' Prints A1:C3
    Debug.Print Sheet1.Range("A1").Resize(3, 3).Address
    
End Sub

 
When we want to resize our destination range we can simply use the source range size.

In other words, we use the row and column count of the source range as the parameters for resizing:

' https://excelmacromastery.com/
Sub Resize()

    Dim rgSrc As Range, rgDest As Range
    
    ' Get all the data in the current region
    Set rgSrc = Sheet1.Range("A1").CurrentRegion

      ' Get the range destination
    Set rgDest = Sheet2.Range("A1")
    Set rgDest = rgDest.Resize(rgSrc.Rows.Count, rgSrc.Columns.Count)
    
    rgDest.Value2 = rgSrc.Value2

End Sub

 
We can do the resize in one line if we prefer:

' https://excelmacromastery.com/
Sub ResizeOneLine()

    Dim rgSrc As Range
    
    ' Get all the data in the current region
    Set rgSrc = Sheet1.Range("A1").CurrentRegion
    
    With rgSrc
        Sheet2.Range("A1").Resize(.Rows.Count, .Columns.Count).Value2 = .Value2
    End With
    
End Sub

Reading Values to variables

We looked at how to read from one cell to another. You can also read from a cell to a variable. A variable is used to store values while a Macro is running. You normally do this when you want to manipulate the data before writing it somewhere. The following is a simple example using a variable. As you can see the value of the item to the right of the equals is written to the item to the left of the equals.

' https://excelmacromastery.com/
Public Sub UseVariables()

    ' Create
    Dim number As Long

    ' Read number from cell
    number = Sheet1.Range("A1").Value2

    ' Add 1 to value
    number = number + 1

    ' Write new value to cell
    Sheet1.Range("A2").Value2 = number

End Sub

 
To read text to a variable you use a variable of type String:

' https://excelmacromastery.com/
Public Sub UseVariableText()

    ' Declare a variable of type string
    Dim text As String

    ' Read value from cell
    text = Sheet1.Range("A1").Value2

    ' Write value to cell
    Sheet1.Range("A2").Value2 = text

End Sub

 
You can write a variable to a range of cells. You just specify the range on the left and the value will be written to all cells in the range.

' https://excelmacromastery.com/
Public Sub VarToMulti()

    ' Read value from cell
    Sheet1.Range("A1:B10").Value2 = 66

End Sub

 
You cannot read from multiple cells to a variable. However you can read to an array which is a collection of variables. We will look at doing this in the next section.

How to Copy and Paste Cells

If you want to copy and paste a range of cells then you do not need to select them. This is a common error made by new VBA users.

Note: We normally use Range.Copy when we want to copy formats, formulas, validation. If we want to copy values it is not the most efficient method.
I have written a complete guide to copying data in Excel VBA here.

 
You can simply copy a range of cells like this:

Range("A1:B4").Copy Destination:=Range("C5")

 
Using this method copies everything – values, formats, formulas and so on. If you want to copy individual items you can use the PasteSpecial property of range.

 
It works like this

Range("A1:B4").Copy
Range("F3").PasteSpecial Paste:=xlPasteValues
Range("F3").PasteSpecial Paste:=xlPasteFormats
Range("F3").PasteSpecial Paste:=xlPasteFormulas

 
The following table shows a full list of all the paste types

Paste Type
xlPasteAll
xlPasteAllExceptBorders
xlPasteAllMergingConditionalFormats
xlPasteAllUsingSourceTheme
xlPasteColumnWidths
xlPasteComments
xlPasteFormats
xlPasteFormulas
xlPasteFormulasAndNumberFormats
xlPasteValidation
xlPasteValues
xlPasteValuesAndNumberFormats

Reading a Range of Cells to an Array

You can also copy values by assigning the value of one range to another.

Range("A3:Z3").Value2 = Range("A1:Z1").Value2

 
The value of  range in this example is considered to be a variant array. What this means is that you can easily read from a range of cells to an array. You can also write from an array to a range of cells. If you are not familiar with arrays you can check them out in this post.  

 
The following code shows an example of using an array with a range:

' https://excelmacromastery.com/
Public Sub ReadToArray()

    ' Create dynamic array
    Dim StudentMarks() As Variant

    ' Read 26 values into array from the first row
    StudentMarks = Range("A1:Z1").Value2

    ' Do something with array here

    ' Write the 26 values to the third row
    Range("A3:Z3").Value2 = StudentMarks

End Sub

 
Keep in mind that the array created by the read is a 2 dimensional array. This is because a spreadsheet stores values in two dimensions i.e. rows and columns

Going through all the cells in a Range

Sometimes you may want to go through each cell one at a time to check value.

 
You can do this using a For Each loop shown in the following code

' https://excelmacromastery.com/
Public Sub TraversingCells()

    ' Go through each cells in the range
    Dim rg As Range
    For Each rg In Sheet1.Range("A1:A10,A20")
        ' Print address of cells that are negative
        If rg.Value < 0 Then
            Debug.Print rg.Address + " is negative."
        End If
    Next

End Sub

 
You can also go through consecutive Cells using the Cells property and a standard For loop.

 
The standard loop is more flexible about the order you use but it is slower than a For Each loop.

' https://excelmacromastery.com/
Public Sub TraverseCells()
 
    ' Go through cells from A1 to A10
    Dim i As Long
    For i = 1 To 10
        ' Print address of cells that are negative
        If Range("A" & i).Value < 0 Then
            Debug.Print Range("A" & i).Address + " is negative."
        End If
    Next
 
    ' Go through cells in reverse i.e. from A10 to A1
    For i = 10 To 1 Step -1
        ' Print address of cells that are negative
        If Range("A" & i) < 0 Then
            Debug.Print Range("A" & i).Address + " is negative."
        End If
    Next
 
End Sub

Formatting Cells

Sometimes you will need to format the cells the in spreadsheet. This is actually very straightforward. The following example shows you various formatting you can add to any range of cells

' https://excelmacromastery.com/
Public Sub FormattingCells()

    With Sheet1

        ' Format the font
        .Range("A1").Font.Bold = True
        .Range("A1").Font.Underline = True
        .Range("A1").Font.Color = rgbNavy

        ' Set the number format to 2 decimal places
        .Range("B2").NumberFormat = "0.00"
        ' Set the number format to a date
        .Range("C2").NumberFormat = "dd/mm/yyyy"
        ' Set the number format to general
        .Range("C3").NumberFormat = "General"
        ' Set the number format to text
        .Range("C4").NumberFormat = "Text"

        ' Set the fill color of the cell
        .Range("B3").Interior.Color = rgbSandyBrown

        ' Format the borders
        .Range("B4").Borders.LineStyle = xlDash
        .Range("B4").Borders.Color = rgbBlueViolet

    End With

End Sub

Main Points

The following is a summary of the main points

  1. Range returns a range of cells
  2. Cells returns one cells only
  3. You can read from one cell to another
  4. You can read from a range of cells to another range of cells.
  5. You can read values from cells to variables and vice versa.
  6. You can read values from ranges to arrays and vice versa
  7. You can use a For Each or For loop to run through every cell in a range.
  8. The properties Rows and Columns allow you to access a range of cells of these types

What’s Next?

Free VBA Tutorial If you are new to VBA or you want to sharpen your existing VBA skills then why not try out the The Ultimate VBA Tutorial.

Related Training: Get full access to the Excel VBA training webinars and all the tutorials.

(NOTE: Planning to build or manage a VBA Application? Learn how to build 10 Excel VBA applications from scratch.)

In this Article

  • Ranges and Cells in VBA
    • Cell Address
    • Range of Cells
    • Writing to Cells
    • Reading from Cells
    • Non Contiguous  Cells
    • Intersection of  Cells
    • Offset from a Cell or Range
    • Setting Reference to a Range
    • Resize a Range
    • OFFSET vs Resize
    • All Cells in Sheet
    • UsedRange
    • CurrentRegion
    • Range Properties
    • Last Cell in Sheet
    • Last Used Row Number in a Column
    • Last Used Column Number in a Row
    • Cell Properties
    • Copy and Paste
    • AutoFit Contents
  • More Range Examples
    • For Each
    • Sort
    • Find
    • Range Address
    • Range to Array
    • Array to Range
    • Sum Range
    • Count Range

Ranges and Cells in VBA

Excel spreadsheets store data in Cells. Cells are arranged into Rows and Columns. Each cell can be identified by the intersection point of it’s row and column (Exs. B3 or R3C2).

An Excel Range refers to one or more cells (ex. A3:B4)

Cell Address

A1 Notation

In A1 notation, a cell is referred to by it’s column letter (from A to XFD) followed by it’s row number(from 1 to 1,048,576). This is called a cell address.

In VBA you can refer to any cell using the Range Object.

' Refer to cell B4 on the currently active sheet
MsgBox Range("B4")

' Refer to cell B4 on the sheet named 'Data'
MsgBox Worksheets("Data").Range("B4")

' Refer to cell B4 on the sheet named 'Data' in another OPEN workbook
' named 'My Data'
MsgBox Workbooks("My Data").Worksheets("Data").Range("B4")

R1C1 Notation

In R1C1 Notation a cell is referred by R followed by Row Number then letter ‘C’ followed by the Column Number. eg B4 in R1C1 notation will be referred by R4C2. In VBA you use the Cells Object to use R1C1 notation:

' Refer to cell R[6]C[4] i.e D6
Cells(6, 4) = "D6"

Range of Cells

A1 Notation

To refer to a more than one cell use a “:” between the starting cell address and last cell address. The following will refer to all the cells from A1 to D10:

Range("A1:D10")

R1C1 Notation

To refer to a more than one cell use a “,” between the starting cell address and last cell address. The following will refer to all the cells from A1 to D10:

Range(Cells(1, 1), Cells(10, 4))

Writing to Cells

To write values to a cell or contiguous group of cells, simple refer to the range, put an = sign and then write the value to be stored:

' Store F5 in cell with Address F6
Range("F6") = "F6"

' Store E6 in cell with Address R[6]C[5] i.e E6
Cells(6, 5) = "E6"

' Store A1:D10 in the range A1:D10
Range("A1:D10") = "A1:D10"
' or
Range(Cells(1, 1), Cells(10, 4)) = "A1:D10"

Reading from Cells

To read values from cells, simple refer to the variable to store the values, put an = sign and then refer to the range to be read:

Dim val1
Dim val2

' Read from cell F6
val1 = Range("F6")

' Read from cell E6
val2 = Cells(6, 5)

MsgBox val1
Msgbox val2

Note: To store values from a range of cells, you need to use an Array instead of a simple variable.

Non Contiguous  Cells

To refer to non contiguous  cells use a comma between the cell addresses:

' Store 10 in cells A1, A3, and A5
Range("A1,A3,A5") = 10


' Store 10 in cells A1:A3 and D1:D3) 
Range("A1:A3, D1:D3") = 10

VBA Coding Made Easy

Stop searching for VBA code online. Learn more about AutoMacro — A VBA Code Builder that allows beginners to code procedures from scratch with minimal coding knowledge and with many time-saving features for all users!

automacro

Learn More

Intersection of  Cells

To refer to non contiguous  cells use a space between the cell addresses:

' Store 'Col D' in D1:D10
' which is Common between A1:D10 and D1:F10
Range("A1:D10 D1:G10") = "Col D"

Offset from a Cell or Range

Using the Offset function, you can move the reference from a given Range (cell or group of cells) by the specified number_of_rows, and number_of_columns.

Offset Syntax

Range.Offset(number_of_rows, number_of_columns)

Offset from a cell

' OFFSET from a cell A1
' Refer to cell itself
' Move 0 rows and 0 columns
Range("A1").Offset(0, 0) = "A1"

' Move 1 rows and 0 columns
Range("A1").Offset(1, 0) = "A2"

' Move 0 rows and 1 columns
Range("A1").Offset(0, 1) = "B1"

' Move 1 rows and 1 columns
Range("A1").Offset(1, 1) = "B2"

' Move 10 rows and 5 columns
Range("A1").Offset(10, 5) = "F11"

Offset from a Range

' Move Reference to Range A1:D4 by 4 rows and 4 columns
' New Reference is E5:H8
Range("A1:D4").Offset(4,4) = "E5:H8"

Setting Reference to a Range

To assign a range to a range variable: declare a variable of type Range then use the Set command to set it to a range. Please note that you must use the SET command as RANGE is an object:

' Declare a Range variable
Dim myRange as Range

' Set the variable to the range A1:D4
Set myRange = Range("A1:D4")

' Prints $A$1:$D$4
MsgBox myRange.Address

VBA Programming | Code Generator does work for you!

Resize a Range

Resize method of Range object changes the dimension of the reference range:

Dim myRange As Range

' Range to Resize
Set myRange = Range("A1:F4")

' Prints $A$1:$E$10
Debug.Print myRange.Resize(10, 5).Address

Top-left cell of the Resized range is same as the top-left cell of the original range

Resize Syntax

Range.Resize(number_of_rows, number_of_columns)

OFFSET vs Resize

Offset does not change the dimensions of the range but moves it by the specified number of rows and columns. Resize does not change the position of the original range but changes the dimensions to the specified number of rows and columns.

All Cells in Sheet

The Cells object refers to all the cells in the sheet (1048576 rows and 16384 columns).

' Clear All Cells in Worksheets
Cells.Clear

UsedRange

UsedRange property gives you the rectangular range from the top-left cell used cell to the right-bottom used cell of the active sheet.

Dim ws As Worksheet
Set ws = ActiveSheet

' $B$2:$L$14 if L2 is the first cell with any value 
' and L14 is the last cell with any value on the
' active sheet
Debug.Print ws.UsedRange.Address

CurrentRegion

CurrentRegion property gives you the contiguous rectangular range from the top-left cell to the right-bottom used cell containing the referenced cell/range.

Dim myRange As Range

Set myRange = Range("D4:F6")

' Prints $B$2:$L$14
' If there is a filled path from D4:F16 to B2 AND L14
Debug.Print myRange.CurrentRegion.Address

' You can refer to a single starting cell also

Set myRange = Range("D4") ' Prints $B$2:$L$14

AutoMacro | Ultimate VBA Add-in | Click for Free Trial!

Range Properties

You can get Address, row/column number of a cell, and number of rows/columns in a range as given below:

Dim myRange As Range

Set myRange = Range("A1:F10")

' Prints $A$1:$F$10
Debug.Print myRange.Address

Set myRange = Range("F10")

' Prints 10 for Row 10
Debug.Print myRange.Row

' Prints 6 for Column F
Debug.Print myRange.Column

Set myRange = Range("E1:F5")
' Prints 5 for number of Rows in range
Debug.Print myRange.Rows.Count

' Prints 2 for number of Columns in range
Debug.Print myRange.Columns.Count

Last Cell in Sheet

You can use Rows.Count and Columns.Count properties with Cells object to get the last cell on the sheet:

' Print the last row number
' Prints 1048576
Debug.Print "Rows in the sheet: " & Rows.Count

' Print the last column number
' Prints 16384
Debug.Print "Columns in the sheet: " & Columns.Count

' Print the address of the last cell
' Prints $XFD$1048576
Debug.Print "Address of Last Cell in the sheet: " & Cells(Rows.Count, Columns.Count)

Last Used Row Number in a Column

END property takes you the last cell in the range, and End(xlUp) takes you up to the first used cell from that cell.

Dim lastRow As Long

lastRow = Cells(Rows.Count, "A").End(xlUp).Row

Last Used Column Number in a Row

Dim lastCol As Long

lastCol = Cells(1, Columns.Count).End(xlToLeft).Column

END property takes you the last cell in the range, and End(xlToLeft) takes you left to the first used cell from that cell.

You can also use xlDown and xlToRight properties to navigate to the first bottom or right used cells of the current cell.

AutoMacro | Ultimate VBA Add-in | Click for Free Trial!

Cell Properties

Common Properties

Here is code to display commonly used Cell Properties

Dim cell As Range
Set cell = Range("A1")

cell.Activate
Debug.Print cell.Address
' Print $A$1

Debug.Print cell.Value
' Prints 456
' Address

Debug.Print cell.Formula
' Prints =SUM(C2:C3)

' Comment
Debug.Print cell.Comment.Text

' Style
Debug.Print cell.Style

' Cell Format
Debug.Print cell.DisplayFormat.NumberFormat

Cell Font

Cell.Font object contains properties of the Cell Font:

Dim cell As Range

Set cell = Range("A1")

' Regular, Italic, Bold, and Bold Italic
cell.Font.FontStyle = "Bold Italic"
' Same as
cell.Font.Bold = True
cell.Font.Italic = True

' Set font to Courier
cell.Font.FontStyle = "Courier"

' Set Font Color
cell.Font.Color = vbBlue
' or
cell.Font.Color = RGB(255, 0, 0)

' Set Font Size
cell.Font.Size = 20

Copy and Paste

Paste All

Ranges/Cells can be copied and pasted from one location to another. The following code copies all the properties of source range to destination range (equivalent to CTRL-C and CTRL-V)

'Simple Copy
Range("A1:D20").Copy 
Worksheets("Sheet2").Range("B10").Paste

'or
' Copy from Current Sheet to sheet named 'Sheet2'
Range("A1:D20").Copy destination:=Worksheets("Sheet2").Range("B10")

Paste Special

Selected properties of the source range can be copied to the destination by using PASTESPECIAL option:

' Paste the range as Values only
Range("A1:D20").Copy
Worksheets("Sheet2").Range("B10").PasteSpecial Paste:=xlPasteValues

Here are the possible options for the Paste option:

' Paste Special Types
xlPasteAll
xlPasteAllExceptBorders
xlPasteAllMergingConditionalFormats
xlPasteAllUsingSourceTheme
xlPasteColumnWidths
xlPasteComments
xlPasteFormats
xlPasteFormulas
xlPasteFormulasAndNumberFormats
xlPasteValidation
xlPasteValues
xlPasteValuesAndNumberFormats

AutoFit Contents

Size of rows and columns can be changed to fit the contents using AutoFit:

' Change size of rows 1 to 5 to fit contents 
Rows("1:5").AutoFit

' Change size of Columns A to B to fit contents 
Columns("A:B").AutoFit

More Range Examples

It is recommended that you use Macro Recorder while performing the required action through the GUI. It will help you understand the various options available and how to use them.

AutoMacro | Ultimate VBA Add-in | Click for Free Trial!

For Each

It is easy to loop through a range using For Each construct as show below:

For Each cell In Range("A1:B100")
    ' Do something with the cell
Next cell

At each iteration of the loop one cell in the range is assigned to the variable cell and statements in the For loop are executed for that cell. Loop exits when all the cells are processed.

Sort

Sort is a method of Range object. You can sort a range by specifying options for sorting to Range.Sort. The code below will sort the columns A:C based on key in cell C2. Sort Order can be xlAscending or xlDescending. Header:= xlYes should be used if first row is the header row.

   Columns("A:C").Sort key1:=Range("C2"), _
      order1:=xlAscending, Header:=xlYes

Find

Find is also a method of Range Object. It find the first cell having content matching the search criteria and returns the cell as a Range object. It return Nothing if there is no match.

Use FindNext method (or FindPrevious) to find next(previous) occurrence.

Following code will change the font to “Arial Black” for all cells in the range which start with “John”:

For Each c In Range("A1:A100")
    If c Like "John*" Then
        c.Font.Name = "Arial Black"
    End If
Next c

Following code will replace all occurrences of  “To Test” to “Passed” in the range specified:

With Range("a1:a500")
    Set c = .Find("To Test", LookIn:=xlValues)
    If Not c Is Nothing Then
        firstaddress = c.Address
        Do
            c.Value = "Passed"
            Set c = .FindNext(c)
        Loop While Not c Is Nothing And c.Address <> firstaddress
    End If
End With

It is important to note that you must specify a range to use FindNext. Also you must provide a stopping condition otherwise the loop will execute forever. Normally address of the first cell which is found is stored in a variable and loop is stopped when you reach that cell again. You must also check for the case when nothing is found to stop the loop.

Range Address

Use Range.Address to get the address in A1 Style

MsgBox Range("A1:D10").Address
' or
Debug.Print Range("A1:D10").Address

Use xlReferenceStyle (default is xlA1) to get addres in R1C1 style

MsgBox Range("A1:D10").Address(ReferenceStyle:=xlR1C1)
' or
Debug.Print Range("A1:D10").Address(ReferenceStyle:=xlR1C1) 

This is useful when you deal with ranges stored in variables and want to process for certain addresses only.

AutoMacro | Ultimate VBA Add-in | Click for Free Trial!

Range to Array

It is faster and easier to transfer a range to an array and then process the values. You should declare the array as Variant to avoid calculating the size required to populate the range in the array. Array’s dimensions are set to match number of values in the range.

Dim DirArray As Variant
' Store the values in the range to the Array

DirArray = Range("a1:a5").Value

' Loop to process the values
For Each c In DirArray
    Debug.Print c
Next

Array to Range

After processing you can write the Array back to a Range. To write the Array in the example above to a Range you must specify a Range whose size matches the number of elements in the Array.

Use the code below to write the Array to the range D1:D5:

Range("D1:D5").Value = DirArray 

Range("D1:H1").Value = Application.Transpose(DirArray)

Please note that you must Transpose the Array if you write it to a row.

Sum Range

SumOfRange = Application.WorksheetFunction.Sum(Range("A1:A10"))
Debug.Print SumOfRange

You can use many functions available in Excel in your VBA code by specifying Application.WorkSheetFunction. before the Function Name as in the example above.

Count Range

' Count Number of Cells with Numbers in the Range
CountOfCells = Application.WorksheetFunction.Count(Range("A1:A10"))
Debug.Print CountOfCells

' Count Number of Non Blank Cells in the Range
CountOfNonBlankCells = Application.WorksheetFunction.CountA(Range("A1:A10"))
Debug.Print CountOfNonBlankCells

Written by: Vinamra Chandra

Range Examples | Cells | Declare a Range Object | Select | Rows | Columns | Copy/Paste | Clear | Count

The Range object, which is the representation of a cell (or cells) on your worksheet, is the most important object of Excel VBA. This chapter gives an overview of the properties and methods of the Range object. Properties are something which an object has (they describe the object), while methods do something (they perform an action with an object).

Range Examples

Place a command button on your worksheet and add the following code line:

Range(«B3»).Value = 2

Result when you click the command button on the sheet:

Excel VBA Range Example

Code:

Range(«A1:A4»).Value = 5

Result:

Range Example

Code:

Range(«A1:A2,B3:C4»).Value = 10

Result:

Range Example

Note: to refer to a named range in your Excel VBA code, use a code line like this:

Range(«Prices»).Value = 15

Cells

Instead of Range, you can also use Cells. Using Cells is particularly useful when you want to loop through ranges.

Code:

Cells(3, 2).Value = 2

Result:

Cells in Excel VBA

Explanation: Excel VBA enters the value 2 into the cell at the intersection of row 3 and column 2.

Code:

Range(Cells(1, 1), Cells(4, 1)).Value = 5

Result:

Cells

Declare a Range Object

You can declare a Range object by using the keywords Dim and Set.

Code:

Dim example As Range
Set example = Range(«A1:C4»)

example.Value = 8

Result:

Declare a Range Object in Excel VBA

Select

An important method of the Range object is the Select method. The Select method simply selects a range.

Code:

Dim example As Range
Set example = Range(«A1:C4»)

example.Select

Result:

Select Method

Note: to select cells on a different worksheet, you have to activate this sheet first. For example, the following code lines select cell B7 on the third worksheet from the left.

Worksheets(3).Activate
Worksheets(3).Range(«B7»).Select

Rows

The Rows property gives access to a specific row of a range.

Code:

Dim example As Range
Set example = Range(«A1:C4»)

example.Rows(3).Select

Result:

Rows Property

Note: border for illustration only.

Columns

The Columns property gives access to a specific column of a range.

Code:

Dim example As Range
Set example = Range(«A1:C4»)

example.Columns(2).Select

Result:

Columns Property

Note: border for illustration only.

Copy/Paste

The Copy and Paste method are used to copy a range and to paste it somewhere else on the worksheet.

Code:

Range(«A1:A2»).Select
Selection.Copy

Range(«C3»).Select
ActiveSheet.Paste

Result:

Copy/Paste Method

Although this is allowed in Excel VBA, it is much better to use the code line below which does exactly the same.

Range(«C3:C4»).Value = Range(«A1:A2»).Value

Clear

To clear the content of an Excel range, you can use the ClearContents method.

Range(«A1»).ClearContents

or simply use:

Range(«A1»).Value = «»

Note: use the Clear method to clear the content and format of a range. Use the ClearFormats method to clear the format only.

Count

With the Count property, you can count the number of cells, rows and columns of a range.

Count Property

Note: border for illustration only.

Code:

Dim example As Range
Set example = Range(«A1:C4»)

MsgBox example.Count

Result:

Count Cells

Code:

Dim example As Range
Set example = Range(«A1:C4»)

MsgBox example.Rows.Count

Result:

Count Rows

Note: in a similar way, you can count the number of columns of a range.

Ranges are a key concept in Excel, and knowing how to work with them is essential for anyone who wants to program or automate their work using Excel VBA. 

In this tutorial, we’ll take a look at how to work with Excel ranges in VBA. We’ll start by discussing what a Range object is. Then, we’ll look at the different ways of referencing a range. Lastly, we’ll explore various examples of how to work with ranges using VBA code.

Excel VBA: The Range object

The Excel VBA Range object is used to represent a range in a worksheet. A range can be a cell, a group of cells, or even all the 17,179,869,184 cells in a sheet.

When programming with Excel VBA, the Range object is going to be your best friend. That’s because much of your work will focus on manipulating data within sheets. Understanding how to work with the Range object will make it easier for you to perform various actions on cells, such as changing their values, sorting, or doing a copy-paste.

The following is the Excel object hierarchy:

Application > Workbook > Worksheet > Range

You can see that the Excel VBA Range object is a property of the Worksheet object. This means that you can access a range by specifying the name of the sheet and the cell address you want to work with. When you don’t specify a sheet name, by default Excel will look for the range in the active sheet. For example, if Sheet1 is active, then both of these lines will refer to the same cell range:

Range("A1") 
Worksheets("Sheet1").Range("A1")

Let’s have a closer look at how to reference a range in the section below. 

Figure 05. A SUMIFS VBA code basic example

Excel VBA Tutorial in 20 Minutes

Referencing a range of cells in Excel VBA

Referring to a Range object in Excel VBA can be done in several ways. We’ll discuss the basic syntax and some alternatives that you might want to use, depending on your needs.

Excel VBA: Syntax for specifying a cell range

To refer to a range that consists of one cell, for example, cell D5, you can use the syntax below: 

Range("D5")

To refer to a range of cells, you have two acceptable syntaxes. For example, A1 through D5 can be specified using any one below:

Range("A1:D5")
Range("A1", "D5")

To refer to a range outside the active sheet, you need to include the worksheet name. Here’s an example:

Worksheets("Sheet1").Range("A1:D5")

To refer to an entire row, for example, Row 5:

Range("5:5")

To refer to an entire column, for example, Column D:

Range("D:D")

Excel VBA also allows you to refer to multiple ranges at once by using a comma to separate each area. For example, see the below syntax used for referring to all ranges shown in the image:

Range("B2:D8, F4:G5")

Figure 2.1. Excel VBA referring to multiple ranges

Tip: Notice that all of the syntaxes above use double quotes to enclose the range address. To make it quicker for you to type, you can use shortcuts that involve using square brackets without quotes, as shown in the table below:

Syntax Shortcut
Range("D5") [D5]
Range("A1:D5") [A1:D5]
Range("5:5") [5:5]
Range("B2:D8, F4:G5") [B2:D8, F4:G5]

Excel VBA: Referencing a named range

You have probably already used named ranges in your worksheets. They can be found under Name Manager in the Formulas tab.

To refer to a range named MyRange, use the following code:

Range("MyRange")

Remember to enclose the range’s name in double quotes. Otherwise, Excel thinks that you’re referring to a variable. 

Alternatively, you can also use the shortcut syntax discussed previously. In this case, double quotes aren’t used:

[MyRange]

Excel VBA: Referencing a range using the Cells property

Another way to refer to a range is by using the Cells property. This property takes two arguments: 

Cells(Row, Column) 

You must use a numeric value for Row, but you may use either a numeric or string value for Column. Both of these lines refer to cell D5: 

Cells(5, "D") 
Cells(5, 4) 

The advantage of using the Cells property to refer to ranges becomes clear when you need to loop through rows or columns. You can create a more readable piece of code by using variables as the Cells arguments in a looping. 

Excel VBA: Referencing a range using the Offset property

The Offset property provides another handy means for referring to ranges. It allows you to refer to a cell based on the location of another cell, such as the active cell. 

Like the Cells property, the Offset property has two parameters. The first determines how many rows to offset, while the second represents the number of columns to offset. Here is the syntax:

Range.Offset(RowOffset, ColumnOffset)

For example, the following code refers to cell D5 from cell A1:

Range("A1").Offset(4,3)

Figure 2.4. Excel VBA An example of referencing a range using the Offset property

The negative numbers refer to cells that are above or below the range of values. For example, a -2 row offset refers to two rows above the range, and a -1 column offset refers to a column to the left of the range. The following example refers to cell A1:

Range("D3").Offset(-2, -3)

If you need to go over only a row or a column, but not both, you don’t have to enter both the row and the column parameters. You can also use 0 as one or both of the arguments. For example, the following lines refer to D5:

Range("D5").Offset(0, 0)
Range("D2").Offset(3, 0)
Range("G5").Offset(, -3)

Let’s take a look at some of the most common range examples. These examples will show you how to use VBA to select and manipulate ranges in your worksheets. Some of these examples are complete procedures, while others are code snippets that you can just copy-paste to your own Sub to try.

Excel VBA: Select a range of cells

To select a range of cells, use the Select method. 

The following line selects a range from A1 to D5 in the active worksheet:

Range("A1:D5").Select

To select a range from A1 to the active cell, use the following line: 

Range("A1", ActiveCell).Select

The following code selects from the active cell to 3 rows below the active cell and five columns to the right: 

Range(ActiveCell, ActiveCell.Offset(3, 5)).Select

It’s important to note that when you need to select a range on a specific worksheet, you need to ensure that the correct worksheet is active. Otherwise, an error will occur. For example, you want to select B2 to J5 on Sheet1. The following code will generate an error if Sheet1 is not active:

Worksheets("Sheet1").Range("B2:J5").Select

Instead, use these two lines of code to make your code work as expected:

Worksheets("Sheet1").Activate 
Range("B2:J5").Select

Excel VBA: Set values to a range

The following statement sets a value of 100 into cell C7 of the active worksheet:

Range("C7").Value = 100

The Value property allows you to represent the value of any cell in a worksheet. It’s a read/write property, so you can use it for both reading and changing values.

You can also set values of a range of any size. The following statement enters the text “Hello” into each cell in the range A1:C7 in Sheet2:

Worksheets("Sheet2").Range("A1:C7").Value = "Hello"

Value is the default property for a Range object. This means that if you don’t provide any properties in your range, Excel will use this Value property. 

Both of the following lines enter a value of 100 into cell C7 of the active worksheet: 

Range("C7").Value = 100
Range("C7") = 100

Excel VBA: Copy range to another sheet

To copy and paste a range in Excel VBA, you use the Copy and Paste methods. The Copy method copies a range, and the Paste method pastes it into a worksheet. It might look a bit complicated but let’s see what each does with an example below. 

Let’s say you have Orders data, as shown in the below screenshot, which is imported from Airtable every day using Coupler.io. This tool allows users to do it automatically on the schedule they want with just a few clicks and no coding required. 

Coupler.io data integration tool

In addition, they can combine data from other different sources (such as Jira, Mailchimp, etc.) into one destination for analysis purposes.

Figure 3.3. Excel VBA Copy range example

As you can see, the data starts from B2. You want to copy only range B2:C11 and paste them to Sheet2 at the same address. The following is an example Sub you can use:

Sub CopyRangeToAnotherSheet()
    Sheets("Sheet1").Activate
    Range("B2:C11").Select
    Selection.Copy
    
    Sheets("Sheet2").Activate
    Range("B2").Select
    ActiveSheet.Paste
End Sub

Alternatively, you can also use a single line of code as shown below:

Sub CopyRangeToAnotherSheet2()
    Worksheets("Sheet1").Range("B2:C11").Copy Worksheets("Sheet2").Range("B2")
End Sub

The above Sub procedure takes advantage of the fact that the Copy method can use an argument that corresponds to the destination range for the copy operation. Notice that actually, you don’t have to select a range before doing something with it.

Excel VBA: Dynamic range example

In many cases, you may need to copy a range of cells but don’t know exactly how many rows and columns it has. For example, if you use Coupler.io or other integration tools to import data from an external app into Excel on a daily schedule, the number of rows may change over time.

How can you determine this dynamic range? One solution is to use the CurrentRegion property. This property returns an Excel VBA Range object within its boundaries. As long as the data is surrounded by one empty row and one empty column, you can select it with CurrentRegion.

The following line selects the contiguous range around Cell B2:

Range("B2").CurrentRegion.Select

Figure 3.4.1. Excel VBA Dynamic range example 1

Now, let’s say you want to select only Columns B and C of the range, and from the second row, you can use the following line:

Range("B2", Range("C2").End(xlDown)).Select

Figure 3.4.2. Excel VBA Selecting columns in a dynamic range

You can now do whatever you want with your selected range — copy or move it to another sheet, format it, and so on.

If you want to find the last row of a used range using Excel VBA, it’s also possible without selecting anything. Here’s the line you can use to find the row number of Column B’s last row data:

' Find the row number of Column B's last row data
RowNumOfLastRow = Cells(Rows.Count, 2).End(xlUp).Row


' Result: 11
MsgBox RowNumOfLastRow

Excel VBA: Loop for each cell in a range 

For looping each cell in a range, the For Each loop is an excellent choice. This type of loop is great for looping through a collection of objects such as cells in a range, worksheets in a workbook, or other collections.

The following procedure shows how to loop through each cell in Range B2:K11. We use an object variable named Obj, which refers to the cell being processed. Within the loop, the code checks if the cell contains a formula and then sets its color to blue.

Sub LoopForEachCell()
    Dim obj As Range
    For Each obj In Range("B2:K11")
        If obj.HasFormula Then obj.Font.Color = vbBlue
    Next obj
End Sub

Excel VBA: Loop for each row in a range

When looping through rows (or columns), you can use the Cells property to refer to a range of cells. This makes your code more readable compared to when you’re using the Range syntax. 

For example, to loop for each row in range B2:K11 and bold all the cells from Column I to K, you might write a loop like this:

Sub LoopForEachRow()
    For i = 1 To 11
        Range("I" & i & ":K" & i).Font.Bold = True
    Next i
End Sub

Instead of typing in a range address, you can use the Cells property to make the loop easier to read and write. For example, the code below uses the Cells and Resize properties to find the required cell based on the active cell:

Sub LoopForEachRow2()
    For i = 1 To 11
        Cells(i, "I").Resize(, 3).Font.Bold = True
    Next i
End Sub

Excel VBA: Clear a range

There are three ways to clear a range in Excel VBA. 

The first is to use the Clear method, which will clear the entire range, including cell contents and formatting. 

The second is to use the ClearContents method, which will clear the contents of the range but leave the formatting intact. 

The third is to use the ClearFormats method, which will clear the formatting of the range but leave the contents intact.

For example, to clear a range B1 to M15, you can use one of the following lines of code below, based on your needs:

Range("B1:M15").Clear
Range("B1:M15").ClearContents
Range("B1:M15").ClearFormats

Excel VBA: Delete a range

When deleting a range, it differs from just clearing a range. That’s because Excel shifts the remaining cells around to fill up your deleted range. 

The code below deletes Row 5 using the Delete method:

Range("5:5").Delete

To delete a range that is not a complete row or column, you have to provide an argument (such as xlToLeft, xlUp — based on your needs) that indicates how Excel should shift the remaining cells.

For example, the following code deletes cell B2 to M10, then fills the resulting gap by shifting the other cells to the left:

Range("B2:M10").Delete xlToLeft

Excel VBA: Delete rows with a specific condition in a range

You can also use a VBA code to delete rows with a specific condition. For example, let’s try to delete all the rows with a discount of 0 from the below sheet:

Figure 3.9. Excel VBA example Delete range with a condition

Here’s an example Sub you may want to use:

Sub DeleteWithCondition()
    For i = 3 To 11
        If Cells(i, "F").Value = 0 Then
            Cells(i, 1).EntireRow.Delete
        End If
    Next i
End Sub

The above code loops from Row 3 to 11. In each loop, it checks the discount value in Column F and removes the entire row if the value equals 0.

Excel VBA: Find values in a range 

With the below data, suppose you want to find if there is an order with OrderNumber equal to 1003320 and output its cell address. 

Figure 3.10. Excel VBA Find a value in a range example

You can use the Find method in this case, as shown in the below code:

Sub FindOrder()
    Dim Rng As Range
     
    Set Rng = Range("B3:B11").Find("1003320")
     
    If Rng Is Nothing Then
        MsgBox "The OrderNumber not found."
    Else
        MsgBox Rng.Address
    End If

End Sub

The output of the above code will be the first occurrence of the search value in the specified range. If the value is not found, a message box showing info that the order is not found will appear.

Excel VBA: Add alрhаbеtѕ using Rаngе .Offset

The following is an example of a Sub that adds alphabets A-Z in a range. The code uses Offset to refer to a cell below the active cell in a loop.

Sub AddAlphabetsAZ()
    Dim i As Integer
    
    ' Use 97 To 122 for lowercase letters
    For i = 65 To 90
        ActiveCell.Value = Chr(i)
        ActiveCell.Offset(1, 0).Select
    Next i
End Sub

To use the Sub, ѕеlесt a сеll where you want tо start thе alphabets. Then, run it by pressing F5. The code will insert A-Z to the cells downward. 

Excel VBA: Add auto-numbers to a range with a variable from user input

Juѕt lіkе inserting alphabets as shown in the previous example, you саn аlѕо іnѕеrt auto-numbers іn уоur worksheet automatically. This can be helpful when you work with large data.

The following is an example of a Sub that adds auto-numbers to your Excel sheet:

Sub AddAutoNumbers()
    Dim i As Integer
    
    On Error GoTo ErrorHandler
    
    i = InputBox("Enter the maximum number: ", "Enter a value")
    
    For i = 1 To i
        ActiveCell.Value = i
        ActiveCell.Offset(1, 0).Select
    Next i
    
ErrorHandler:
    Exit Sub
End Sub

Tо uѕе the соdе, уоu need tо ѕеlесt the сеll frоm where you want tо start thе auto-numbеrѕ. Then, run the Sub. In the message box that appears, enter the maximum value for the auto-numbers and сlісk OK.

Figure 3.12. Excel VBA set a range using a variable example

Excel VBA: Sum a range 

Imagine that you have written a Sub procedure to import Orders.csv into an Excel sheet:

By the way, you can automate import of CSV to Excel without any coding if you use Coupler.io

Figure 3.13. Excel VBA Sum a range example

You want to sum up all the discount values and put the result in J12. The following code that utilizes the Sum worksheet function would handle that: 

Sub GetTotalDiscount()
    Range("J12") = WorksheetFunction.Sum(Range("J2:J10"))
End Sub

Excel VBA: Sort a range 

The Sort method sorts values in a range based on the criteria you provide.

Suppose you have the following sheet:

Figure 3.14. Excel VBA Sort a range example

To sort the above data based оn thе vаluеѕ іn Column D, you can use the following code:

Sub SortBySingleColumn()
    Range("A1:E10").Sort Key1:=Range("D1"), Order1:=xlAscending, Header:=xlYes
End Sub

You can also sort the range by multiple columns. For example, to sort by Column B and Column D, here’s an example code you can use:

Sub SortByMultipleColumns()
    Range("A1:E10").Sort _
        Key1:=Range("B1"), Order1:=xlAscending, _
        Key2:=Range("D1"), Order2:=xlAscending, _
        Header:=xlYes
End Sub

Here are the arguments used in the above methods:

  • Kеу: It specifies the field you want to use in ѕоrting thе data. 
  • Ordеr: It ѕресіfies whеthеr уоu wаnt tо sort the dаtа іn аѕсеndіng or dеѕсеndіng order. 
  • Header: It spесіfies whеthеr уоur data hаѕ hеаdеrѕ оr nоt.

Excel VBA: Range to array

Arrays are powerful because they can actually make the code run faster. Especially when working with large data, you can use arrays to make all the processing happen in memory and then write the data to the sheet once.

For example, suppose you have the following sheet:

Figure 3.15.1. Excel VBA Sort range example

The following Sub uses a variable X, which is a Variant data type, to store the value of Range A2:E10. Variants can hold any type of data, including arrays. 

Sub RangeToArray()
    Dim X As Variant
    X = Range("A2:E10")
End Sub

You can then treat the X variable as though it were an array. The following line returns the value of cell A6:

MsgBox X(5, 1)
' Result: 1003320

Now, let’s say you want to calculate the total order using the following calculation:

Quantity * Price - Discount

Rather than doing calculation and writing the result for each row using a looping, you can store the calculation result in an array OrderTotal as shown in the below code and write the result once:

Sub CalculateTotalOrder()
    Dim X As Variant, OrderTotal As Variant
    X = Range("A2:E10")
    
    ReDim OrderTotal(UBound(X))
    
    For i = LBound(X) To UBound(X)
        OrderTotal(i - 1) = X(i, 3) * X(i, 4) - X(i, 5)
    Next i
    
    Range("F1") = "OrderTotal"
    
    Range("F2").Resize(UBound(OrderTotal)) = _
        Application.Transpose(OrderTotal)
    
End Sub

Here’s the final result:

Figure 3.15.2. Excel VBA Sort range result

Subscript out of range: Excel VBA Runtime error 9

This error message often happens when you try to access a range of cells in a worksheet that has been deleted or renamed.

Figure 4. Excel VBA Subscript out of range error

Let’s say your code expected a worksheet named Setting. For some reason, this sheet is renamed Settings. So, the error occurs every time the below Sub runs:

Sub GetSettings()
    Worksheets("Setting").Select
    x = Range("A1").Value
End Sub

To prevent the runtime error happening again, you may want to add an error handler code like this below:

Sub GetSettings()
    On Error Resume Next

    ws = Worksheets("Setting")
    Name = ws.Name
    
    If Not Err.Number = 0 Then
        MsgBox "Expected to find a Setting worksheet, but it is missing."
        Exit Sub
    End If
    On Error GoTo 0
    
    ws.Select
    x = Range("A1").Value
End Sub

Excel VBA Range — Final words

Thank you for reading our Excel VBA Range tutorial. We hope that you’ve found it helpful! And if there’s anything else about Excel programming or other topics that interest you, be sure to check out our other Excel tutorials.

In addition, you may find that Coupler.io is a valuable tool for you if you’re looking for an easy way to pull and combine your data from multiple sources into one destination for analysis and reporting. This tool also lets you specify the range address of your imported data so you can keep all of your calculations (including. formulas) in the sheets.

Thanks again for reading, and happy coding!

  • Fitrianingrum Seto

    Senior analyst programmer

Back to Blog

Focus on your business

goals while we take care of your data!

Try Coupler.io

Like this post? Please share to your friends:
  • Vba excel range from cells
  • Vba excel range format
  • Vba excel save to my documents
  • Vba excel table column
  • Vba excel save image