Working with ARRAY VARIABLES (VBA)
This post will teach you how to work with Excel arrays in visual basic for applications (VBA).
Why do you need arrays? Excel is much quicker at executing tasks with arrays than working with values on a worksheet. Arrays exist in your computer's RAM memory while workbooks exist on your hard drive.
Working with data from your computer's RAM memory is much faster.
What's on this page
- How to dimension an array variable and declare data type
- How to redimension an array variable
- n-dimensional arrays
- Finding the starting and ending index number of an array
- How to manipulate an array
- How to clear an array
- How to copy array values to a worksheet
- How to transpose an array
- Get data from a worksheet to an array variable
- How to copy an array
- How to pass an array to a macro
- How to pass an array to a function
- How to determine the number of dimensions in an array
- How to split a text string
1. Declare an array variable
A variable can store one value, an array variable can store multiple values.
The following line declares pets as a String array variable. The parentheses shows that this is an array variable.
Sub Macro1() Dim pets() As String End Sub
You can also specify how many values you want to store in the array. The macro below declares variable pets as a string array, it can store 6 values. 0 to 5.
Sub Macro1() Dim pets(5) As String End Sub
If you want to start with 1 instead of 0 you can do that too. This variable can store 5 values, 1 to 5.
Sub Macro1() Dim pets(1 to 5) As String End Sub
2. Redimensioning an array variable
You can also change the amount of values an array variable can store any time in the macro, using the ReDim statement.
Sub Macro1() Dim pets(1 to 2) As String pets(1) = "dog" Msgbox Ubound(pets) ReDim pets(1 to 3) Msgbox pets(1) & " " & Ubound(pets) End Macro
Note that this clears all previous saved array values.
3. n-dimensional arrays
The example arrays shown above have one dimension but it is possible to have up to 60000 dimensions. You are probably going to use one or two dimensions most of the time.
3.1 One-dimensional arrays
You can assign values to an array in your macro or user defined function. The following macro shows you how.
Sub Macro1() Dim pets(1 to 2) As String pets(1) = "dog" pets(2) = "cat" End Sub
In this macro 2 values can be stored pets(1 to 2). The index number in the pets variable tells excel where to save the value in the array. pets(index)
You can also grab values from a worksheet and save them to an array.
Sub Macro1() Dim pets(1 to 2) As String pets(1) = Worksheets("Sheet1").Range("A1").value pets(2) = Worksheets("Sheet1").Range("A2").value End Sub
If you have many values this macro might do the work but this method is relatively slow.
Sub Macro1() Dim pets(1 to 100) As String For i = 1 to 100 pets(i) = Worksheets("Sheet1").Range("A" & i).value Next i End Sub
There is a quicker way to transfer values from a worksheet to an array that I will tell you about later in this post.
3.2 Two-dimensional arrays
This macro shows you how to populate a 2-dimensional array. The first argument is the row number and the second is the column number, pets(row, column)
Sub Macro1() Dim pets(1 to 2, 1 to 2) pets(1,1) = "dog" pets(1,2) = 5 pets(2,1) = "cat" pets(2,2) = 9 End Sub
This picture is a visual presentation of the array variable. The italic numbers show the position of each value in the array.
3.3 Three-dimensional arrays
It is also possible to have arrays with three dimensions. The best analogy I can think of is if the first argument is the row number, the second argument is column number, the third argument is then like worksheets.
Sub Macro1() Dim pets(1 to 2, 1 to 2, 1 to 2) pets(1,1,1) = "dog" pets(1,2,1) = 5 pets(2,1,1) = "cat" pets(2,2,1) = 9 pets(1,1,2) = "snake" pets(1,2,2) = 3 pets(2,1,2) = "fish" pets(2,2,2) = 4 End Sub
4. Array size - Finding the starting and ending index number of an array
Each element or value has a index number indicating its position in the array. Arrays always have a lower and upper limit, the Lbound statement returns the lower limit and the Ubound statement returns the upper limit. These functions are very useful. If the lower limit is 1 and the upper limit is 5, the array contains 5 values.
4.1 One-dimensional array
The following macro uses the LBound and Ubound statements to determine the size of the array variable.
Sub Macro1() Dim pets(1 To 10) Msgbox "LBound: " & LBound(pets) & " Ubound: " & Ubound(pets) End sub
4.2 Two-dimensional array
This macro shows you how to figure out the size of a 2 dimensional array variable.
Sub Macro1() Dim pets(1 To 5, 1 To 3) MsgBox "Lower limit 1-dim: " & LBound(pets, 1) & " Upper limit 1-dim:" & UBound(pets, 1) & " Lower limit 2-dim: " & LBound(pets, 2) & " Upper limit 2-dim: " & UBound(pets, 2) End Sub
4.3 Three-dimensional array
Sub Macro1() Dim pets(1 To 5, 1 To 3, 1 To 2) MsgBox "Lower limit 1-dim: " & LBound(pets, 1) & " Upper limit 1-dim:" & UBound(pets, 1) & " Lower limit 2-dim: " & LBound(pets, 2) & " Upper limit 2-dim: " & UBound(pets, 2) & " Lower limit 3-dim: " & LBound(pets, 3) & " Upper limit 3-dim: " & UBound(pets, 3) End Sub
5. Manipulate an array
You can change dimensions of an array and still keep all values. But you need to declare the array variable with empty parentheses or you will get this compile error: "Array already dimensioned"
Sub Macro1() Dim pets() As String ReDim pets(1 To 5) pets(2) = "dog" ReDim Preserve pets(1 To UBound(pets) + 1) MsgBox "Lbound(pets): " & LBound(pets) & " Ubound(pets): " & UBound(pets) & "pets(2): " & pets(2) End Sub
You can only ReDim the last dimension, the following array has 2 dimensions, the boundaries are 1 to 5 and 1 to 2.
Sub Macro1() Dim pets() As String ReDim pets(1 To 5, 1 To 2) ReDim Preserve pets(1 to Ubound(pets,1) , 1 To UBound(pets,2) + 1) MsgBox "Lbound(pets,1): " & LBound(pets,1) & " Ubound(pets,1): " & UBound(pets,1) & vbNewLine & "Lbound(pets,2): " & LBound(pets,2) & " Ubound(pets,2): " & UBound(pets,2) End Sub
The ReDim Preserve statement changes the last dimension the 2-dimensional array in the macro above. The boundaries are now 1 to 5 and 1 to 3, this picture shows you that.
Excel is really slow when it comes to manipulating arrays, it is better to try to minimize the number of times you use ReDim Preserve by guessing how many elements you need.
6. Clear an array
You can use the ReDim statement to clear all saved array values.
Sub Macro1() Dim pets(1 to 2) As String pets(1) = "dog" Msgbox Ubound(pets) ReDim pets(1 to 3) Msgbox pets(1) & " " & Ubound(pets) End Macro
You can also use the Erase function
Sub Macro1() Dim pets(1 to 2) As String pets(1) = "cat" Erase pets End Sub
7. Transfer array values to a worksheet
&
7.1 Macro
This macro returns an array to worksheet Sheet1
Sub Macro1() Dim pets(1 to 2) As String pets(1) = "dog" pets(2) = "cat" Worksheets("Sheet1").Range("A1:B1") = pets End Macro
As you can see it returns theses values horizontally. It is possible to return values vertically also, se Transpose later in this post.
7.2 User defined function
The following user defined function (udf) returns array values but you need to enter it as an array formula.
Function ArrTest Dim pets(1 to 2) As String pets(1) = "dog" pets(2) = "cat" ArrTest = pets End Macro
Here are the steps on how to enter an array formula:
- Select cell A1:B1
- Type =ArrTest()
- Press and hold CTRL + SHIFT
- Press Enter
If you enter the udf correctly the formula bar shows {=ArrTest()}
If you fail to enter this udf as an array formula it might show the first value in the array in all cells, the formula bar shows =ArrTest()
8. Transpose an array
A 1-dimensional array is always shown horizontally on worksheet, to change that you can use the Transpose method and rearrange the values vertically.
Sub Macro1() Dim pets(1 to 2) As String pets(1) = "dog" pets(2) = "cat" Worksheets("Sheet1").Range("A1:A2") = Application.Transpose(pets) End Sub
If your array is larger than 65536 the transpose statement will return an error, this macro will not work.
Sub Macro1() Dim pets(1 To 65537) As String Dim i As Single For i = 1 To 65537 pets(i) = i Next i Worksheets("Sheet1").Range("A1:A65537") = Application.Transpose(pets) End Sub
The Transpose statement returns Run-time error '13': Type mismatch.
However, there is a workaround to overcome this array limit. The following macro returns an array vertically to cell range A1:A65537 and Transpose is not even used. The downside is that you can't change the size of the first dimension using ReDim Preserve.
Sub Macro1() Dim pets(1 To 65537, 1 To 1) As Single For i = 1 To 65537 pets(i, 1) = i Next i Worksheets("Sheet1").Range("A1:A65537") = pets End Sub
Be aware that if you use Transpose with an array that is larger than 65536 in excel 2013 or 2016 no error is shown.
9. Fetch data from a worksheet
This macro retrieves 65537 values from cell range A1:A65537 and it does it super fast.
Sub Macro1() Dim pets() As Variant pets = Worksheets("Sheet1").Range("A1:A65537").Value MsgBox "LBound(pets,1):" & LBound(pets, 1) & " Ubound(pets,1): " & UBound(pets, 1) & vbNewLine & "LBound(pets,2): " & LBound(pets, 2) & " UBound(pets,2): " & UBound(pets, 2) End Sub
It returns a 2-dimensional array even if you only grab one column of data.
9.1 Copy data from an excel defined table
You can also copy values from an excel defined table to an array.
Sub Macro1() Dim pets() As Variant pets = Range("Table1").Value MsgBox "LBound(pets,1):" & LBound(pets, 1) & " Ubound(pets,1): " & UBound(pets, 1) & vbNewLine & "LBound(pets,2): " & LBound(pets, 2) & " UBound(pets,2): " & UBound(pets, 2) End Sub
Range("Table1").Value returns all values except the headers, use Table1[#All] if you want all values. If you want to copy only column "Name" to an array use Table1[Name].
10. Copy an array
To copy an entire array simply use the equal sign.
Sub Macro1() Dim pets(1 To 2) As Variant Dim dogs() As Variant pets(1) = "Labrador Retriever" pets(2) = "Golden Retriever" dogs = pets MsgBox dogs(1) & vbNewLine & dogs(2) End Sub
Back to top
10.1 Copy a column to a new array
Application.Index statement allows you to copy a section of an array.
dogs = Application.Index(pets, 0, 1) copies column 1 from array pets to a new array named dogs.
Copying a column to a new array creates a 2-dimensional array but if you copy a row the new array is 1-dimensional, see the two next macro examples below.
Sub Macro1() Dim pets(1 To 2, 1 To 2) As Variant Dim dogs() As Variant pets(1, 1) = "Labrador Retriever" pets(2, 1) = "Golden Retriever" pets(1, 2) = "Boxer" pets(2, 2) = "Beagle" dogs = Application.Index(pets, 0, 1) MsgBox dogs(1, 1) & vbNewLine & dogs(2, 1) End Sub
10.2 Copy a row to a new array
Copying a row (horizontal values) from an array creates a new array with only one dimension.
Sub Macro1() Dim pets(1 To 2, 1 To 2) As Variant Dim dogs() As Variant pets(1, 1) = "Labrador Retriever" pets(2, 1) = "Golden Retriever" pets(1, 2) = "Boxer" pets(2, 2) = "Beagle" dogs = Application.Index(pets, 2, 0) MsgBox dogs(1) & vbNewLine & dogs(2) End Sub
As you might have suspected there is a problem with the INDEX function. It can't handle arrays larger than 65536 values and Microsoft seems to do nothing about it, the error has been there since excel 2007.
11. Send an array to a macro
Macro2 creates and populates a new array and then runs Macro1 using the array as an argument.
Sub Macro1(val() As String) MsgBox val(1) vbNewLine val(2) End Sub
Sub Macro2() Dim pets(1 To 2) As String pets(1) = "Labrador Retriever" pets(2) = "Golden Retriever" Call Macro1(pets) End Sub
12. Pass an array to a function
The following two functions demonstrates how to pass arrays between functions. User defined function Func2 copies values from a worksheet to an array, it then passes the array to Func1. Func1 transposes the values and sends them back. Func2 then returns the values to a worksheet.
Function Func1(val() As Variant) Func1 = Application.Transpose(val) End Function
Function Func2(rng As Range) Dim temp() As Variant Dim temp1() As Variant temp = rng.Value Func2 = Func1(temp) End Function
You can also send an array from a macro to a udf.
13. Determine the number of dimensions in an array
User defined function CountDim counts the number of dimensions in an array.
Function CountDim(val() As Variant) Dim i As Single On Error Resume Next For i = 1 To 60000 chk = LBound(val, i) If Err <> 0 Then Exit For Next i On Error GoTo 0 CountDim = i - 1 End Function
Function Test() Dim arr(1 To 10, 1 To 5, 1 To 3, 1 To 5, 1 To 3) Test = CountDim(arr) End Function
Function Test returns 5, there are five dimensions in this array:
14. Split a text string
The split function allows you to separate a text string using a delimiter. It returns a 1-dimensional array (0 to n) and that makes it interesting in this context.
Function CountWords(rng As Range) Text = Split(rng, " ") CountWords = UBound(Text) + 1 End Function
Arrays category
Array formulas allows you to do advanced calculations not possible with regular formulas.
Excel categories
11 Responses to “Working with ARRAY VARIABLES (VBA)”
Leave a Reply
How to comment
How to add a formula to your comment
<code>Insert your formula here.</code>
Convert less than and larger than signs
Use html character entities instead of less than and larger than signs.
< becomes < and > becomes >
How to add VBA code to your comment
[vb 1="vbnet" language=","]
Put your VBA code here.
[/vb]
How to add a picture to your comment:
Upload picture to postimage.org or imgur
Paste image link to your comment.
Contact Oscar
You can contact me through this contact form
Excellent article on a difficult subject, thanks!
Thanks, Torstein.
Oscar how to reduced my array
For example
Sub test()
Dim arr(1 to 1000,1 to 20)
Dim x,r as range,rw as long,cl as long,j = j + 1
Set r = [A1].currentRegion
x = r.value
For cl = 1 to ubound(x,2)
For rw = 1 to ubound(x)
If x(rw,cl) = "Oscar" then
j = j + 1
arr(j,cl) = x(rw,cl)
End if
Next rw
Next cl
'after finish save data to array
'my ubound(arr,1) = 500
How to reduced my arr
'redim preserve arr(1 to j,1 to 20)
End sub
You can only change the last dimension with redim preserve, count the populated values and then create a new array with the same dimensions as populated values, lastly copy the old array to the new array.
Is there any way to assign an array to an array variable.
Not the "Fetch data from a worksheet" method shown above. I just want to set it within the VBA codes
e.g. something like
Dim FileSuffix(1 To 3) As String
FileSuffix = Array("Pass", "Now", "Future")
Kenneth Lam,
The variable FileSuffixneeds to be dimmed as Variant (not as String).
The function Array always returns a zero-based array.
Is there any way to fastest copy ListColumn DataBodyRange from a Table to a column of determined array?
For example:
I have a table "Material"
No. Code
1 AAA
2 BBB
...
I want to take result or arr()
arr(1,3) = "AAA"
arr(2,3) = "BBB"
...
Hello,
A VBA newbie here. This was a really nice read !
A small query: Can I access the range values passed to a function to assign values to variables defined in the Function? Not really able to get the below code to work.
For eg,
Public Function Func1(val() as variant)
Dim A As Double
Dim B As Double
A = val(0)
B = val(2)
Func1 = A + B
End Function
I need to get variables from a range in the worksheet. The problem is that it recognizes the values as text since it applies quotation marks around each value in the cells. How can I get rid of the quotation marks when I get the values in my code?
Range("A1").Select
Dim SourceRange As Variant
Set SourceRange = Selection.CurrentRegion
rowNumber = SourceRange.Rows.Count
colNumber = SourceRange.Columns.Count
ReDim finalSheetList(rowNumber, colNumber)
finalSheetList = SourceRange.Value
For example I want to get finalSheetList(1, 2) as a variable but it appears to be text.I would like to use these variables within my code.
Range:
colDONumber colMI
colCINumber colMP
colDPNumber colMP
Thanks
Amazingly explained.. thank you so much
Muchas gracias por el aporte.
Consulta. Se pueden declarar matrices con columnas de distinto tipo de variable?. Por ejemplo algo así: Dim MMM(9 as string,99 as date,999 as long). Muchas gracias.