Arrays in Excel VBA
An array is like a table that contains elements of the same data type.
By using an array as a variable you can avoid declaring a lot of variables. Instead you collect them in one place, your array, and then you can look them up, when you need to read or write a value.
Every element in an array has an index number, and you can find the element by using the index number as a reference. You can also loop through arrays.
An important thing to remember is that (at least in older versions of Excel) the first element has 0 (zero) as its index number, and in that case element number 99 is in fact element number 100. If you find that confusing, you can declare otherwise by writing the following at the top of the VBA module:
Then 1 is standard instead of zero, but you can also do it, when you declare your array (see later) and that is recommended.
There are two types of arrays: The static and the dynamic. With a static array you know beforehand, how many elements it can contain, and then it is locked, while a dynamic array can be made smaller or bigger at runtime.
I'll get back to dynamic arrays later, and at the end of this page I explain the terms UBound and LBound. I will also show, how you can copy an array very fast to a range in the spreadsheet.
You can copy the examples by highlighting them with the mouse, copy by pressing CTRL+C and paste into a VBA module by pressing CTRL+V.
Let us look at the static array:
The static array
You declare a static array by writing something like this:
Dim MyArray(100) As Integer
Where you say that it contains 100 elements of the data type Integer. Or (recommended):
Dim MyArray(1 To 100) As String
Where you specify that the first element has index number one. This is good practice, because you avoid errors if you reuse the code later. You can also write:
Dim MyArray(2000 To 2010) As Integer
This could be convenient if the array contains the years 2000 to 2010. Here is a small example of the use of a static array.
Sub ArrayTest()
Dim MyArray(1 To 100) As String
Dim iCount As Integer
For iCount = 1 To 100
MyArray(iCount) = "Number " & iCount + 1
Next
MsgBox MyArray(100)
For iCount = 1 To 100
Range("A1").Offset(iCount - 1, 0).Value = MyArray(iCount)
Next
End Sub
TIP!
If you want an array for different data types, declare it as a Variant knowing full well that it will use more memory than "leaner" data types.
Arrays with more dimensions
Well, if it was just a one dimensional array (table) I needed, I would usually prefer using a Collection, because I find collections simpler and easier to use.
But unlike collections arrays can have more dimensions, and that is a smart thing! Here is a simple example of a two dimensional array:
Sub TwoDimensionalArray()
Dim MyArray(1 To 10, 1 To 2) As Integer
Dim iCount As Integer
For iCount = 1 To 10
MyArray(iCount, 1) = iCount
MyArray(iCount, 2) = iCount + 1
Next
For iCount = 1 To 10
Range("A1").Offset(iCount - 1, 0).Value = MyArray(iCount, 1)
Range("B1").Offset(iCount - 1, 0).Value = MyArray(iCount, 2)
Next
End Sub
The procedure above could also be names and telephone numbers, and if you also wanted addresses, you could declare "1 To 3" instead of "1 To 2". With addresses in the third "column" you would have to declare the array as a Variant and not Integer.
It could be done as below, but before you copy the macro into a module and run it, you should write 10 names in cell A1 to A10, 10 numbers ("telephone numbers") in B1 to B10 and 10 somethings in cell C1 to C10.
Sub TwoDimArray()
Dim MyArray(1 To 10, 1 To 3) As Variant
Dim rRange As Range
Dim iCount As Integer
Dim iCount2 As Integer
Set rRange = Range("A1:A10")
For iCount = 1 To 10
With rRange.Item(iCount)
MyArray(iCount, 1) = .Value
MyArray(iCount, 2) = .Offset(0, 1).Value
MyArray(iCount, 3) = .Offset(0, 2).Value
End With
Next
Set rRange = Range("A12:A22")
For iCount = 10 To 1 Step -1
iCount2 = iCount2 + 1
With rRange.Item(iCount2)
.Value = MyArray(iCount, 1)
.Offset(0, 1).Value = MyArray(iCount, 2)
.Offset(0, 2).Value = MyArray(iCount, 3)
End With
Next
Set rRange = Nothing
End Sub
You can add more dimensions to an array, much like Chinese boxes. A three-dimensional array can be visualised as a cube, but with more than three dimensions it becomes difficult to visualise - it will be like fractals.
Imagine the first elements as "tree trunks". Every trunk can have branches. Each branch has etc. etc.
Dynamic arrays
If you don't know how many elements you need in the array, you can declare a dynamic array and then change the size in runtime (add or remove).
A dynamic array is declared like this:
Dim DynArray() As Variant
When you get to the point, where you need to put values into your array, you can resize it with the command "ReDim". For instance:
ReDim DynArray(1 To 100)
or
ReDim DynArray(1 To lCount)
where lCount is a variable of the data type Long.
You can redimension a dynamic array anytime with the ReDim command, but if you don't use the word "Preserve", any existing content will be erased.
Say for instance that you have an array with 100 elements, and you want to increase it to 200 and preserve the content, you write:
ReDim Preserve DynArray(1 To 200)
LBound and UBound
When you work with dynamic arrays, you may not know the number of elements - the array may have been rezised in runtime by one or more variables.
In that situation (e.g. when looping through the array) you can use LBound to find the "low boundary" and UBound to find the upper.
If for instance you have an array that has been dimensioned runtime from 1 to 99, just like:
ReDim Preserve DynArray(1 To 99)
The code
UBound(DynArray)
will return 99, and
LBound(DynArray)
will return 1.
If the array has more dimensions like e.g.
ReDim Preserve DynArray(1 To 100, 5 To 10)
The following
UBound(DynArray, 1)
UBound(DynArray, 2)
LBound(DynArray, 1)
LBound(DynArray, 2)
will return 100, 10, 1 and 5, because 1 and 2 point are different dimensions.
Fast copying of an array to a range
In some of the examples above I have shown, how you can copy the contents of an array to a range in the spreadsheet by looping through the array and filling the cells one by one.
That works fine with small arrays, but if they get big, it is a slow method, and there is a much smarter and much faster way - provided it is a two dimensional array like a table.
See below how to do it. The point is to define a range and an array with the same dimensions - i.e. number of rows and columns. Once the array has been filled, it is fast as lightning to copy it to the range by writing:
MyRange.Value = MyArray
As simple as that! Here is an example doing just that. Because a range with more columns is two dimensional by nature, our array must also be two dimensional.
Sub ArrayToRange()
Dim MyArray() As Integer
Dim rRange As Range
Dim iNumber As Integer
Dim iCount As Integer
Dim iCount2 As Integer
Set rRange = Range("A1:N30")
With rRange
ReDim MyArray(1 To .Rows.Count, 1 To .Columns.Count)
End With
Application.ScreenUpdating = False
iNumber = 0
For iCount = 1 To rRange.Rows.Count
For iCount2 = 1 To rRange.Columns.Count
MyArray(iCount, iCount2) = iNumber + 1
iNumber = iNumber + 1
Next
Next
rRange.Value = MyArray
BeforeExit:
Set rRange = Nothing
Application.ScreenUpdating = True
Exit Sub
ErrorHandle:
MsgBox Err.Description
Resume BeforeExit
End Sub
That was a bit about arrays. Related subjects are Arrays and ranges, Collections and Classes and Class Collections.
You can find more information (and more advanced) about arrays at Pearson or Microsoft.
To top
Related:
|