Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array being resized when passing a Range from worksheet

Tags:

arrays

excel

vba

I have reading various questions relating to arrays, dimensioning them and dynamic versus static arrays. I also understand there is something called a staggered array, which is an array of arrays if I understand correctly.

It is my understanding that static arrays cannot be resized and are set when they are dimensioned.

Dim myStArray (1 to 3, 1 to 3) as Integer

A Dynamic array can be resized and only the last dimension can be preserved if desired but it appears you can only do so with variant type.

Dim myDyArray ()as variant
ReDim MyDyArray (3,3)

When I look at MyDyArray in the locals window I can see MyDyArray + and if I expand the plus I get 3 sub arrays with all entries being empty.

when I assign a worksheet range to the array that is smaller than the redimensioned size of the array, the array shrinks to match the size of the range even though is was not ReDim'ed.

MyDyArray = ThisWorkbook.Worksheet(1).Range("A3:C3")

After a line like that when I look in locals, there is only 1 subarray and the other 2 empty arrays are gone. Furthermore when I then try to access MyDyArray(2,1) I will get an error and the watch window will tell me its a subscript out of range.

It is my understanding that the fastest and efficient way to pass a range of individual cell values to an array is to pass the entire range as above.

My Question is how can I pass the information from the worksheet to the array without having the dynamic array resized on me?

Will I just have to step through the array cell by cell to pass the information?

Dim MyDyArray () as Variant

ReDim MyDyArray (3,3)

With ThisWorkbook.Worksheet(1)

For row = 1 to 3
     For col = 1 to 3
          IF row <= .Range("A3:C3").rows.count then
               MyDyArray(row,col) = .Cells(row,col).value
          Else
               MyDyArray(row,col) = 0
          End If
     Next col
Next row

If I initialize the array with zeros before passing the range will it still resize?

Dim MyDyArray () as Variant

ReDim MyDyArray (3,3)

For row = 1 to 3
     For col = 1 to 3
          MyDyArray(row,col) = 0
     Next col
Next row

MyDyArray = ThisWorkbook.Worksheet(1).Range("A3:C3")
like image 363
Forward Ed Avatar asked May 14 '26 09:05

Forward Ed


1 Answers

A dynamic array can not only be resized, its variable can also be assigned to.
.Value returns an array, it gets stored in your array variable overwriting an array that used to be there. No resizing is happening here.

If you want to keep the size (but not the identity) of your array, resize your Range to have the same shape as your array before you query the .Value:

Dim MyDyArray() as Variant
ReDim MyDyArray (1 To 3, 1 To 3)

...

MyDyArray = ThisWorkbook.Worksheets(1).Range("A3").Resize(UBound(MyDyArray, 1) - LBound(MyDyArray, 1) + 1, UBound(MyDyArray, 2) - LBound(MyDyArray, 2) + 1).Value

Naturally that means you will read more values from the sheet that you may want, and every element of your array will be overwritten.
If you'd rather avoid that, fill your array cell by cell - or, if you are concerned with speed, read the entire subchunk in a separate array and then copy element by element from that array into the required subsection of your array.

like image 92
GSerg Avatar answered May 17 '26 07:05

GSerg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!