Creating an Array from a Range in VBA

I'm having a seemingly basic problem but can't find any resources addressing it.

Simply put, I just want to load the contents of a Range of cells (all one column) into an Array.

I am able to accomplish this by means of

DirArray = Array(Range("A1"), Range("A2"))

But for some reason, I cannot create the array when expressed this way:

DirArray = Array(Range("A1:A2"))

My real Range is much longer (and may vary in length), so I don't want to have to individually enumerate the cells this way. Can anyone tell me how to properly load a whole Range into an Array?

With the latter code:

MsgBox UBound(DirArray, 1)

And

MsgBox UBound(DirArray)

Return 0, whereas with the former they return 1.


Just define the variable as a variant, and make them equal:

Dim DirArray As Variant
DirArray = Range("a1:a5").Value

No need for the Array command.


If we do it just like this:

Dim myArr as Variant
myArr = Range("A1:A10")

the new array will be with two dimensions. Which is not always somehow comfortable to work with:

enter image description here

To get away of the two dimensions, when getting a single column to array, we may use the built-in Excel function “Transpose”. With it, the data becomes in one dimension:

enter image description here

If we have the data in a row, a single transpose will not do the job. We need to use the Transpose function twice:

enter image description here

Note: As you see from the screenshots, when generated this way, arrays start with 1, not with 0. Just be a bit careful.

Edit June.2021: In newer versions of Excel, the function is: Application.WorksheetFunctions.Transpose()


Using Value2 gives a performance benefit. As per Charles Williams blog

Range.Value2 works the same way as Range.Value, except that it does not check the cell format and convert to Date or Currency. And thats probably why its faster than .Value when retrieving numbers.

So

DirArray = [a1:a5].Value2

Bonus Reading

  • Range.Value: Returns or sets a Variant value that represents the value of the specified range.
  • Range.Value2: The only difference between this property and the Value property is that the Value2 property doesn't use the Currency and Date data types.

In addition to solutions proposed, and in case you have a 1D range to 1D array, i prefer to process it through a function like below. The reason is simple: If for any reason your range is reduced to 1 element range, as far as i know the command Range().Value will not return a variant array but just a variant and you will not be able to assign a variant variable to a variant array (previously declared).

I had to convert a variable size range to a double array, and when the range was of 1 cell size, i was not able to use a construct like range().value so i proceed with a function like below.

Public Function Rng2Array(inputRange As Range) As Double()

    Dim out() As Double    
    ReDim out(inputRange.Columns.Count - 1)

    Dim cell As Range
    Dim i As Long
    For i = 0 To inputRange.Columns.Count - 1
        out(i) = inputRange(1, i + 1) 'loop over a range "row"
    Next

    Rng2Array = out  
End Function