VBA Arrays

Before I start, let me share a little secret with you… I really dislike VBA arrays.  There just seem to be too many oddities in how they work.  Compared with other programming languages, VBA seems to make arrays overly complicated.  If you feel the same, then you’re in the right place.  This post contains a lot of code examples, which will cover most of your use cases.

Thank you to Jon Peltier for suggesting how I can improve this post.

Table of Contents

Download the example file: Join the free Insiders Program and gain access to the example file used for this post.

File name: 0017 VBA Arrays.zip

What is an array & when to use it?

An array is a list of variables of the same type.  For example, a list of supplier names would be an array.

Let’s assume we have a list of 5 suppliers that can change each month.  Look at the screenshot below as an example:

Top Suppliers List

To hold the supplier list, we could create 5 variables, then assign values from a worksheet to each variable.  This is what the code might look like:

Sub ListSuppliers()

'Create the variables
Dim Supplier1 As String
Dim Supplier2 As String
Dim Supplier3 As String
Dim Supplier4 As String
Dim Supplier5 As String

'Assign values to the suppliers
Supplier1 = ActiveSheet.Range("A2").Offset(0, 0).Value2
Supplier2 = ActiveSheet.Range("A2").Offset(1, 0).Value2
Supplier3 = ActiveSheet.Range("A2").Offset(2, 0).Value2
Supplier4 = ActiveSheet.Range("A2").Offset(3, 0).Value2
Supplier5 = ActiveSheet.Range("A2").Offset(4, 0).Value2

End Sub

That doesn’t seem too bad, does it?  Now imagine we have to list 1,000 suppliers, or 10,000 suppliers; that’s going to be a very dull day of coding.  Unless, of course, we use an array.

Also, what if we have an unknown number of suppliers.  What are we going to do then?  We would need create more variables than we need just to ensure there is enough space.  Again we can turn to a VBA array.

Look at the code below; it creates an array to hold 10,000 suppliers, populated from 10,000 cells in column A. You don’t need to understand it at this stage; instead, just be impressed with how neat and tidy it is. It’s difficult to believe that a VBA array containing a list of 10,000 items takes less code than a list of five variables.

Sub ListSuppliersArray()

Dim Suppliers(1 To 10000) As String
Dim i As Long

For i = LBound(Suppliers) To UBound(Suppliers)

    Suppliers(i) = ActiveSheet.Range("A2").Offset(i - 1, 0).Value2

Next i

End Sub

Using the VBA above, it doesn’t matter if there are 1, 20, 50, 1,000, or 10,000 items, the code will be the same length.  This is the advantage of arrays; we don’t have to write the same code over and over.  Instead we can write one piece of code which add all of the items into an array.

But, it doesn’t end there.  If the values to assign are in a contiguous range, we can reduce the code to just a few lines.  Look at the macro below; a range of 10,000 cells is assigned to a Variant variable type, which automatically creates an array of 10,000 items (no looping required).  Amazing stuff, right?

Sub ListSuppliersArray()

Dim Suppliers As Variant

Suppliers = ActiveSheet.Range("A2:A10001").Value2

End Sub

OK, now we understand the benefits of VBA arrays, let’s learn how to use them.

Static vs. dynamic Arrays

Arrays come in two forms:

  • Static – an array with a fixed number of elements
  • Dynamic – an array where the number of elements is determined as the macro runs.

The difference between the two is how they are created. After that, accessing values, looping through elements and other actions are exactly the same.

Declaring an array as a variable

Arrays are declared in the same way as single value variables.  The critical difference is that when declaring an array parentheses are often used after the variable name.

Declare a single variable

'Declare a string as a single variable
Dim myVariable As String

Declare an array variable

'Declare a string as an array
Dim myArray(1 to 5) As String

Arrays, like other variables can be any variable type.  Integers, strings, objects and ranges, etc., can all be included in an array.

Using variant as an array

A variable declared as a Variant can hold any data type.  Interestingly, a Variant type can also become an array if we assign an array to it.

Look at the code below.  First, a standard variable with a Variant data type is created, then an array is assigned to the variable.  As a result, the variable has become an array, and can be treated the same as other arrays.

Dim arrayAsVariant As Variant 
arrayAsVariant = Array("Alpha", "Bravo", "Charlie")

Create a static array

The following macro creates a static array with 5 elements (1, 2, 3, 4 & 5).

Sub CreateStaticArray()

'Create a static array with 5 elements (1, 2, 3, 4, 5)
Dim arr(1 To 5) As Long

End Sub

By default, arrays have base 0, which means they start counting at 0, rather than 1.  The following macro creates a static array with 6 elements (0, 1, 2, 3, 4, 5).  Notice that the array is created with 5 inside the parentheses, but because of base 0, there are actually 6 elements created.

Sub CreateStaticArrayStartingAtZero()

'Create a static array with 6 elements (0, 1, 2, 3, 4, 5)
Dim arr(5) As Long

End Sub

We can turn arrays into base 1 (i.e., counting starts at 1) by inserting the following code at the top of the code module.

Option Base 1

Create a static two-dimension array

Arrays can contain multiple dimensions (or sub-arrays).  This is much like having data in rows and column.  In the code below, we have created a static array of 3 elements, each of which is its own array containing another 3 elements.

Sub Create2DimensionStaticArray()

Dim arr(1 To 3, 1 To 3) As String

arr(1, 1) = "Alpha"
arr(1, 2) = "Apple"
arr(1, 3) = "Ant"
arr(2, 1) = "Bravo"
arr(2, 2) = "Ball"
arr(2, 3) = "Bat"
arr(1, 1) = "Charlie"
arr(2, 2) = "Can"
arr(3, 3) = "Cat"

End Sub

We’re not limited to just two dimensions, VBA allows us up to 60!  I don’t think I’ve very used more than 3, but it’s good to know that there are so many spare.

Create a dynamic array

The problem with static arrays is that we need to know how many elements are required when we create the array.  But often we don’t know the number of elements, or maybe we want to add and remove elements from the array as we go.  Instead, we can turn to dynamic arrays.
NOTE – The term “dynamic array” in Excel and VBA is not the same; they are entirely different methodologies.
The following macro initially creates a dynamic array with no size.  Then, later in the macro, the array is resized, using ReDim, to create 5 elements, starting at 1.

Sub CreateDynamicArray()

'Create the array
Dim arr() As Long

'Resize the array later in the macro
ReDim arr(1 To 5)

End Sub

A dynamic array can be resized many times during macro execution (we will see this later in this post).

Index locations

Each element of an array has an index number (i.e., the position in the array).

Index of the first element

The following macro displays the index number of the first element in an array.

Sub GetIndexOfFirstElement()

'Create the array
Dim arr As Variant
arr = Array("Alpha", "Bravo", "Charlie")

'Get the index number of the first element
MsgBox LBound(arr)

End Sub

LBound() is a function which returns the lowest item in the array.

Index of the last element

The following macro displays the index number of the last element in an array.

Sub GetIndexOfLastElement()

'Create the array
Dim arr As Variant
arr = Array("Alpha", "Bravo", "Charlie")

'Get the index number of the last item element
MsgBox UBound(arr)

End Sub

UBound() is a function which returns the highest item in the array.

Assigning values to an array

After creating an array, whether dynamic or static, we need a way to assign values to the individual elements.

Assign values to elements individually

The following macro creates a static array, then assigns values to each element individually.

Sub AssignFixedValuesToArray()

Dim arr(1 To 5) As String

arr(1) = "Alpha"
arr(2) = "Bravo"
arr(3) = "Charlie"
arr(4) = "Delta"
arr(5) = "Echo"

End Sub

Assign values to elements with an array list

The following macro demonstrates how to assign values to a dynamic array based on a list of values.

Sub AssignValuesFromListToArray()

'Type must be Variant for method to work
Dim arr As Variant
arr = Array("Alpha", "Bravo", "Charlie")

End Sub

The Array() command is a short way to add values to an array.

Assign values to elements with a string

The following macro splits a string into an array.

Sub SplitStringIntoArray()

Dim arr As Variant
Dim myString As String

'Create list with a by common seperator between each element
myString = "Alpha, Bravo, Charlie, Delta, Echo"

'Turn the list into an array
arr = Split(myString, ", ")

End Sub

Assign values to elements from a range

The following macro creates a 2-dimensional array directly from a range.

Sub ReadRangeToArray()

Dim arr As Variant
arr = ActiveSheet.Range("A1:C3").Value2

End Sub

When using this method, the created array will always contain two-dimensions (just like the rows and column from the range).  So, even if the source range is a single row or column, the array will still contain two-dimensions.

Convert arrays to string and ranges

Having got an array, we can then convert it into either a string or display the values in a range.

Convert array to string

The following code creates an array, then uses the Join function to convert it into a string.

Sub JoinArrayIntoString()

Dim arr As Variant
Dim joinedString As String

'Create an array
arr = Array("Alpha", "Bravo", "Charlie")

'Turn array into a string, each item separated by a comma
joinedString = Join(arr, " ,")

End Sub

Convert array to range

A 2-dimensional array can be written to the cells in a worksheet in either a horizontal or vertical direction.

Sub WriteArrayToRange()

Dim arr As Variant
arr = Array("Alpha", "Bravo", "Charlie", "Delta", "Echo")

'Write array across columns
ActiveSheet.Range("D1:H1") = arr

'Alternative, write an array down rows
'ActiveSheet.Range("D1:D5") = Application.Transpose(arr)

End Sub

Looping through each element in an array

There are two ways to loop through the elements of an array:

  • For loop – Using the LBound and UBound functions to determine the number of times to loop
  • For Each loop – Loops through every item in the array

NOTE – The For Each loop can only read the elements in an array; it cannot be used to change the values assigned to elements.

For loop: single-dimension array

The following example creates a single dimension array, then loops through each element in the array.

Sub ForLoopThroughArray()

Dim arr As Variant
Dim i As Long

arr = Array("Alpha", "Bravo", "Charlie", "Delta", "Echo")

'Loop from the LowerBound to UpperBound items in array
For i = LBound(arr) To UBound(arr)

    MsgBox arr(i)

Next i

End Sub

For loop: multi-dimension array

A For loop can also be used for multi-dimension arrays, as shown in the code below.

Sub ForLoopThrough2DimensionArray()

Dim arr(1 To 3, 1 To 3) As String
Dim i As Long
Dim j As Long

arr(1, 1) = "Alpha"
arr(1, 2) = "Apple"
arr(1, 3) = "Ant"
arr(2, 1) = "Bravo"
arr(2, 2) = "Ball"
arr(2, 3) = "Bat"
arr(3, 1) = "Charlie"
arr(3, 2) = "Can"
arr(3, 3) = "Cat"

For i = LBound(arr) To UBound(arr)

    For j = LBound(arr, 2) To UBound(arr, 2)

        MsgBox arr(i, j)

    Next j

Next i

End Sub

For Each loop: single-dimension array

The For Each loop works on a single or multi-dimension array.  However, it can only read data from an array, it cannot assign values to an array.

Sub ForEachLoopThroughArray()

Dim arr As Variant
Dim arrElement As Variant

arr = Array("Alpha", "Bravo", "Charlie", "Delta", "Echo")

'Loop through array using For Each method
For Each arrElement In arr

    MsgBox arrElement

Next arrElement

End Sub

For Each loop: multi-dimension array

The example below is to illustrate that the For Each loop is identical for both single and multi-dimension arrays.

Sub ForEachLoopThrough2DimensionArray()

Dim arr(1 To 3, 1 To 3) As String
Dim arrElement As Variant

arr(1, 1) = "Alpha"
arr(1, 2) = "Apple"
arr(1, 3) = "Ant"
arr(2, 1) = "Bravo"
arr(2, 2) = "Ball"
arr(2, 3) = "Bat"
arr(3, 1) = "Charlie"
arr(3, 2) = "Can"
arr(3, 3) = "Cat"

'Loop through array
For Each arrElement In arr

    MsgBox arrElement

Next arrElement

End Sub

Check if a value is in an array

We often need to search an array to discover if an item exists.  The following is a reusable function for searching through an array for a specific value.

The result of the function can be:

  • True = The value searched is in the array
  • False = The value searched is not in the array

The function takes two arguments (1) the array and (2) the value to find.

Function IsValueInArray(arr As Variant, find As Variant) As Boolean

Dim arrElement As Variant

'Loop through array
For Each arrElement In arr

    If arrElement = find Then
        IsValueInArray = True
        Exit Function
    End If

Next arrElement

IsValueInArray = False

End Function

The following is an example of how to call the function above; it tells the function to search for the string “Bravo” within the array.  The result returned is True if found, or False if not.

Sub UseFunctionValueInArray()

Dim arr As Variant
Dim arrElement As Variant

arr = Array("Alpha", "Bravo", "Charlie", "Delta", "Echo")

MsgBox IsValueInArray(arr, "Bravo")

End Sub

Find the index of an element in an array

In the previous sections we returned True of False depending on if an item exists.  But often that is not enough, we want to know where it is in the array.  The following is a reusable function which finds a value in an array, then returns the index position:

The result of the function can be:

  • Number returned = The index position of the searched value
  • False = The value searched was not found

The function takes two arguments the value to find and the array to search.

Function PositionInArray(arr As Variant, find As Variant) As Variant

Dim i As Long

For i = LBound(arr) To UBound(arr)

    If arr(i) = find Then

        PositionInArray = i
        Exit Function

    End If

Next i

PositionInArray = False

End Function

The following shows how to use the function above; if the string “Bravo” is found within the array, it will return the index position, or False if not found.

Sub UseFunctionPositionInArray()

Dim arr As Variant
Dim arrElement As Variant

arr = Array("Alpha", "Bravo", "Charlie", "Delta", "Echo")

MsgBox PositionInArray(arr, "Bravo")

End Sub

Resizing an array

As we’ve seen above, dynamic arrays are declared without a size.  Then later in the code, ReDim is used to size the array.  ReDim can be used many times during the macro to resize a dynamic array.

Static arrays cannot be resized, trying to do so, leads to an error.

Array already dimensionedd

When resizing an array with ReDim, the assigned values will be cleared out. To keep the existing values we must use the ReDim Preserve command.

Resize and blank values

The macro below creates, then resizes an array.  After that, the code loops through the array to demonstrate that folowing a ReDim the the values are cleared.

Sub ResizeArraySize()

Dim arr As Variant
Dim arrElement As Variant

arr = Array("Alpha", "Bravo", "Charlie", "Delta", "Echo")

'Array will resize by lose all previous values
ReDim arr(0 To 5)

'Loop through array using For Each method - all elements blank
For Each arrElement In arr

    MsgBox arrElement

Next arrElement

End Sub

Resize array and keep existing values

The following macro creates, then resizes an array using ReDim Preserve.  As the For Each loop demonstrates, by using ReDim Preserve, the values are maintained.

Sub ResizeArraySizeKeepValues()

Dim arr As Variant
Dim arrElement As Variant

arr = Array("Alpha", "Bravo", "Charlie", "Delta", "Echo")

'Array will resize by lose all previous values
ReDim Preserve arr(0 To 5)

'Add additional value into the array
arr(5) = "Foxtrot"

'Loop through array using For Each method - all elements blank
For Each arrElement In arr

    MsgBox arrElement

Next arrElement

End Sub

Sorting array order

The following function sorts an array alphabetically.  The function takes a single argument, the array to be sorted.

Function SortingArrayBubbleSort(arr As Variant)

Dim i As Long
Dim j As Long
Dim temp As Variant

For i = LBound(arr) To UBound(arr) - 1

    For j = i + 1 To UBound(arr)

        If arr(i) > arr(j) Then

            temp = arr(j)
            arr(j) = arr(i)
            arr(i) = temp

        End If

    Next j

Next i

SortingArrayBubbleSort = arr

End Function

The following is an example of how to use the function above.

Sub CallBubbleSort()

Dim arr As Variant
arr = Array("Charlie", "Delta", "Bravo", "Echo", "Alpha")

arr = SortingArrayBubbleSort(arr)

End Sub

Reverse array order

The function below reverses the order of an array.  The function takes the name of an array as the only argument.

Function ReverseArray(arr As Variant)

Dim temp As Variant
Dim i As Long
Dim arrSize As Long
Dim arrMid As Long

arrSize = UBound(arr)
arrMid = (UBound(arr) - LBound(arr)) \ 2 + LBound(arr)

For i = LBound(arr) To arrMid

    temp = arr(arrSize)
    arr(arrSize) = arr(i)
    arr(i) = temp
    arrSize = arrSize - 1

Next i

ReverseArray = arr

End Function

The code below is an example of how to use the function above.

Sub CallReverseArray()

Dim arr As Variant
arr = Array("Alpha", "Bravo", "Charlie", "Delta", "Echo")

arr = ReverseArray(arr)

End Sub

Filter an array

Along with LBound, UBound, Split and Join, another useful built-in function is Filter.

The Filter function returns an array that includes only the elements which contain a sub-string.  In the example below the filteredArr array only includes the elements which contain the letter “o”,

Sub FilterArray()

Dim arr As Variant
Dim filteredArr As Variant
Dim arrElement As Variant

arr = Array("Alpha", "Bravo", "Charlie", "Delta", "Echo")

'Filter array for any elements with the letter "o"
filteredArr = Filter(arr, "o")

'Loop through the filtered array
For Each arrElement In filteredArr

    MsgBox arrElement

Next arrElement

End Sub

The Filter function has 4 arguments:

Filter(SourceArray, Match, [Include], [CompareType])
  • SourceArray – the original array
  • Match – the substring to match
  • Include (default is True if the argument is excluded)
    • True = include the matched items
    • False = exclude the matched items
  • CompareType Include (default is 0 if the argument is excluded):
    • 0 = vbBinaryCompare – The match is case sensitive
    • 1 = vbTextCompare – The match is not case sensitive

Conclusion

Hopefully, this post covers most of your needs.  However, VBA arrays are a vast topic, so make use of online forums to ask specific questions which this post doesn’t answer.


Discover how you can automate your work with our Excel courses and tools.

Excel Academy

Excel Academy
The complete program for saving time by automating Excel.

Excel Automation Secrets

Excel Automation Secrets
Discover the 7-step framework for automating Excel.

Office Scripts Course

Office Scripts: Automate Excel Everywhere
Start using Office Scripts and Power Automate to automate Excel in new ways.

Leave a Comment