Home |
Search |
Today's Posts |
#1
![]()
Posted to microsoft.public.excel.programming
|
|||
|
|||
![]()
This post relates to xl2000, though I believe it’s relevant for later
versions as well. A couple of years ago in this forum it was argued that after Dim MyArray() MyArray = Array(1,2,3) MyArray is not a Variant() array but is a Variant variable containing an array, just as though the snippet were Dim MyArray MyArray = Array(1,2,3) The results of the thread containing the argument were not definitive; no really convincing demonstration was put forth either way. But in recently solving what appeared to be an unrelated matter I have had occasion to focus on a couple of items that resolve the question more satisfactorily. It’s not the Unified Field Theory, but hey, it’s still nice to tidy up a loose end. First some background. The On-line help for the ReDim Statement asserts <<The ReDim statement is used to size or resize a dynamic array that has already been formally declared using a Private, Public, or Dim statement with empty parentheses (without dimension subscripts). . . . If you use the Preserve keyword, you can resize only the last array dimension . . . .. Similarly, when you use Preserve, you can change the size of the array only by changing the upper bound; changing the lower bound causes an error. . . . You can use the ReDim statement repeatedly to change the number of elements and dimensions in an array. [Ed. Note: the following is a key feature] However, you can't declare an array of one data type and later use ReDim to change the array to another data type, UNLESS THE ARRAY IS CONTAINED IN A VARIANT [Emphasis added]. If the array is contained in a Variant, the type of the elements can be changed using an As type clause . . . Recently, keepitcool, a contributor to this forum, pointed out to me the additional possibility, not referred to in the On-line help, of changing the lower bound of a one-dimensional array with ReDim Preserve (it in fact works on the last dimension of a multi-dimensional array as well). He didn’t focus on the distinction between a Variant() array and an array contained within a Variant variable, but I discovered that the technique, like that of changing the array’s data type, works only on the latter and not on a Variant() array. One handy thing the technique enables is changing a loaded one-dimensional dynamic array from 0-based to 1-based or vice versa with the ReDim Preserve construct rather than looping. So two separate features are described above that distinguish between Variant() arrays and Variant variables that contain arrays: The ability to redimension a dynamic array contained within a Variant variable so as to change the data type of its elements (which is documented), and the ability to use ReDim Preserve to change the lower bound of the last dimension of a dynamic array contained in a Variant variable (which is not documented, but which is readily demonstrable). The argument a couple of years ago that Dim MyArray1() led to a Variant variable containing an array was basically: <<<I have done some studying on this issue and I find that in vb version 6, Dim MyArray1() isn't an array of variants. It is a variant at the top level and it contains an array (last 8 bytes point to an array structure) - same structure you get by assigning an array to a variant or picking up a range from a worksheet - it is using a variant at the top level. So when an array is assigned or a range is picked up and you use Dim MyArray1(), MyArray2() MyArray1() = Range("A1:B10") MyArray2() = MyArray1() This is technically identical to Dim MyArray1 as Variant, MyArray2 as Variant myArray1 = Range("A1:B10") myArray2 = MyArray1 in the first case the top level variant gets a new array assigned (pointer assignment) and in the latter case, it gets an initial array assigned (pointer assignment). Their is no advantage (or difference) in using the first construct . . . . You really need to examine the underlying structure of the storage and not rely on empirical testing. VB/VBA does way too much work behind the scenes to make this reliable in many cases - this case in particular. I must say that I never did appreciate the thrust of the argument and its reference to a “variant at the top level”, “the last 8 bytes pointing to an array structure”, “pointer assignments”, and “the underlying structure of the storage”; that’s all somewhat beyond me. But be that as it may, because of the two distinguishing features described above, you can run successfully: Dim MyArray1 As Variant, MyArray2 As Variant MyArray1 = Range("A1:B10") MyArray2 = MyArray1 ReDim Preserve MyArray2(1 To 10, 0 To 1) Debug.Print LBound(MyArray2, 2); UBound(MyArray2, 2) ‘<--Prints 0 1 ReDim MyArray2(1 To 10, 1 To 2) As Integer Debug.Print TypeName(MyArray2) ‘<--Prints Integer() Whereas if you try to run Dim MyArray1(), MyArray2() MyArray1() = Range("A1:B10") MyArray2() = MyArray1() ReDim Preserve MyArray2(1 To 10, 0 To 1) Debug.Print LBound(MyArray2, 2); UBound(MyArray2, 2) ReDim MyArray2(1 To 10, 1 To 2) As Integer Debug.Print TypeName(MyArray2) you will get a Compile error at the ReDim . . . As Integer line-Can’t change data types of array elements; and if you comment out that line you will get a Runtime error at the ReDim Preserve line-Subscript out of range. So however nimble the “underlying structure of the storage” analysis may be, from the errors thrown above it seems abundantly clear that the two constructs are not technically identical and that MyArray1() and MyArray2() are true Variant() arrays and not Variant variables containing arrays (if they were the latter, then, as demonstrated above, there would be no such errors). Alan Beban |
Thread Tools | Search this Thread |
Display Modes | |
|
|
![]() |
||||
Thread | Forum | |||
If Range("C1") is in MyArray | Excel Programming | |||
Can I reset an array to myarray() | Excel Programming | |||
Can I reset an array to myarray() | Excel Programming | |||
Redim MyArray | Excel Programming |