xlvba range to array code example
Example 1: vba array from worksheet data
'In Excel VBA, the quickest way to pull data from a worksheet into a VBA array
'is to do it all at once:
Dim v As Variant
v = Range("a1:b20").Value
'Please note that, here, 'v' is a scalar variable of type Variant. Scalar means
'that 'v' is NOT an array. But interestingly in this case, 'v' can be
'treated exactly like an array. To understand why, please keep reading...
'Variant variables can be assigned many types of values, for example,
'all of the following (and many others) are valid:
v = 123
v = 12.19971
v = "abcdefg"
Set v = New Collection
'IN ADDITION, a Variant can also be assigned an entire array, dynamic or static:
Dim v As Variant, arr() As Long
ReDim arr(1 to 4)
arr(1) = 11
arr(2) = 12
arr(3) = 13
arr(4) = 14
v = vArrA
'Now that the array of Longs 'arr' has been assigned to the Variant 'v', we can
'access the elements directly from 'v':
MsgBox v(4) '<--displays: 14
'A very efficient way to read data from a worksheet range is to directly assign
'the data to a Variant by having that variable point to an array of Variants:
v = Sheet1.Range("a1:b20").Value
'The 'Value' property of the Range object creates a 2D array of Variant
'elements the same size as the specified range, in this case,
'20 rows of 2 columns, with a lower bound of 1 for both array dimensions.
'Here, we assign that array directly to the scalar Variant 'v', all in one go.
'The scalar Variant 'v' can now be treated as an array, even though it is
'actually a scalar variable that points to an array THAT WAS NEVER NAMED:
MsgBox v(2, 20) '<--displays: the value that was in Sheet1, cell B20
'As long as the worksheet range consists of more than one cell, this method
'always results in an array and that array is always 2D. It is never 1D.
'If the range consists of only ONE cell, then this method does NOT create an
'array; instead, it assigns that one cell's scalar value to the Variant 'v'.
'This one-cell treatment must bo gaurded against.
'However, this shortcut method of copying Excel ranges to VBA arrays is
'very convienent and its use is common. The advantage is not only
'extremely concise code; this technique is much faster than copying
'cell-by-cell... and the speed improvement grows with the size of
'the range being copied.
'The code can even be shortened:
v = [Sheet1!a1:b20]
'The square brackets are a shorthand notation for VBA's Evaluate() function.
'This shorthand produces exactly the same results as the previous example,
'because the Evaluate() function returns a Range object in this instance and
'the default property of the Range object is the 'Value' property.
'In the above examples, the Range object is returning its
'default... the Range.Value property. But keep in mind that the
'Range.Value2 property is roughly 20% quicker. So it slightly more
'performant to code these two examples like so:
v = [Sheet1!a1:b20].Value2
v = Sheet1.Range("a1:b20").Value2
'Important: the array created using the 'Value' or 'Value2' properties
' is completely detached from the source range on the
' worksheet. Either can be updated and the changes will NOT
' affect the other.
'Note: VBA utilizes the OLE/COM SAFEARRAY data structure for its
' array implementation:
' https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/2e87a537-9305-41c6-a88b-b79809b3703a
' https://ecs.syr.edu/faculty/fawcett/Handouts/cse775/presentations/BruceMcKinneyPapers/safeArrays.htm
' http://www.roblocher.com/whitepapers/oletypes.html
'
'
'
Example 2: excel vba create an array from a range
v = [a1:b20]
'If v is dimensioned as a variant then he above creates a 2d array,
'20 rows high by 2 columns wide and those 40 array elements contain
'the values from the specified range.
'The square brackets are shorthand notation. Another way to code the
'same thing is:
v = Range("a1:b20")
'In both of the above examples, the Range object is returning its
'default... the Range.Value property. But keep in mind that the
'Range.Value2 property is about 20% quicker. So it could be more
'performant to code these two examples like so:
v = [a1:b20].Value2
v = Range("a1:b20").Value2