|
-
Jul 5th, 2007, 11:36 PM
#1
[RESOLVED] Best way to determine # of array dimensions?
Just curious if there is a way to programmatically determine how many dimensions a dynamic array has. eg:
vb Code:
Sub Test()
Dim varArray As Variant
Dim lngArray() As Long
Debug.Print ArrayDimensions(varArray) & "," & ArrayDimensions(lngArray)
ReDim varArray(9)
ReDim lngArray(9)
Debug.Print ArrayDimensions(varArray) & "," & ArrayDimensions(lngArray)
ReDim varArray(9,9)
ReDim lngArray(9,9)
Debug.Print ArrayDimensions(varArray) & "," & ArrayDimensions(lngArray)
Erase varArray, lngArray
Debug.Print ArrayDimensions(varArray) & "," & ArrayDimensions(lngArray)
End Sub
Function ArrayDimensions(pvarArray As Variant) As Long
' ???
End Function
Which would ideally look like this in the debug window:
Test
0,0
1,1
2,2
0,0
Any ideas?
-
Jul 6th, 2007, 12:01 AM
#2
Re: Best way to determine # of array dimensions?
http://www.codeguru.com/vb/gen/vb_mi...cle.php/c7495/
Get the info from the base using copymemory. Wont work with strings array though.
Last edited by leinad31; Jul 6th, 2007 at 12:15 AM.
-
Jul 6th, 2007, 12:08 AM
#3
Re: Best way to determine # of array dimensions?
How about this?
Code:
Function ArrayDimensions(pvarArray As Variant) As Long
Dim i As Long
Dim n As Long
On Error GoTo CleanUp
Do
i = i + 1
n = UBound(pvarArray, i)
Loop
CleanUp:
ArrayDimensions = i - 1
End Function
-
Jul 6th, 2007, 01:01 AM
#4
Re: Best way to determine # of array dimensions?
Logo, yeah, that's certainly a functional solution, and is likely the best one.
I'm intrigued by the idea of reading the first two bytes of the array base. From what I can gather, I need to read the safe array pointer from the data section of pvarArray, and then somehow directly access the first two bytes it points to.
Here's what I have so far.
vb Code:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Public Function ArrayDimensions(pvarArray As Variant) As Long
Dim lngPointer As Long ' ???
If VarType(pvarArray) < vbArray Then
ArrayDimensions = -1
Else
CopyMemory lngPointer, pvarArray, 4 ' ???
End If
End Function
Clearly, I'm way out of my depth.
How do I skip the first 8 bytes of pvarArray and access the four byte (long) safe array pointer directly?
Once I get that pointer, how do I go to where it's pointing and read the two byte (integer) dimension?
Anyone?
-
Jul 6th, 2007, 01:26 AM
#5
Re: Best way to determine # of array dimensions?
Are you wanting to know the upper and lower bounds, or are you trying to determine how many dimensions it has?
In either case, The shorter the code, the 1)easier to debug 2)faster to run 3)smaller the executable. I would go with his example.
-
Jul 6th, 2007, 01:29 AM
#6
Re: Best way to determine # of array dimensions?
The shorter the code does not always mean faster to run. Easier to debug of course There was a recent topic regarding arrays which randem done a lot of tests showing time it took to execute the code have a look
-
Jul 6th, 2007, 01:35 AM
#7
Re: Best way to determine # of array dimensions?
Dimensions of Array
The method there uses the CopyMemory API and it works very well
-
Jul 6th, 2007, 03:00 AM
#8
Re: Best way to determine # of array dimensions?
Perfect, that's exactly what I was hoping for.
Here's the API solution: (which does work with strings)
Code:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As Any, source As Any, ByVal bytes As Long)
' Returns 0 for unintialized array, -1 for non-array
' Thanks to Francesco Balena of devx.com/vb2themax
Function ArrayDimensionsAPI(pvarArray As Variant) As Long
Const VT_BYREF = &H4000&
Dim lngPointer As Long
Dim intType As Integer
Dim intDimensions As Integer
CopyMemory intType, pvarArray, 2
If (intType And vbArray) <> 0 Then
' Get safe array pointer
CopyMemory lngPointer, ByVal VarPtr(pvarArray) + 8, 4
' If not a typed array, pointer is to a pointer, so resolve
If (intType And VT_BYREF) Then CopyMemory lngPointer, ByVal lngPointer, 4
' If array is initialized...
If lngPointer Then
' Read dimension from header of safe array
CopyMemory intDimensions, ByVal lngPointer, 2
ArrayDimensionsAPI = intDimensions
End If
End If
' Distinguish non-arrays (-1) from uninitialized arrays (0)
If ArrayDimensionsAPI = 0 And Not (VarType(pvarArray) And vbArray) = vbArray Then ArrayDimensionsAPI = -1
End Function
Here's the error trapping solution:
Code:
' Returns 0 for unintialized array, -1 for non-array
Function ArrayDimensions(pvarArray As Variant) As Long
Dim lngTemp As Long
Dim i As Long
On Error Resume Next
Do
i = i + 1
lngTemp = UBound(pvarArray, i)
Select Case Err.Number
Case 13: ArrayDimensions = -1
Case 9: ArrayDimensions = i - 1
End Select
Loop Until Err.Number
End Function
Of course, neither works with UDTs, but just the thought of a multi-dimensional UDT array makes my skin crawl.
Last edited by Ellis Dee; Jul 6th, 2007 at 03:09 AM.
-
Jul 6th, 2007, 09:32 AM
#9
Re: [RESOLVED] Best way to determine # of array dimensions?
why wouldn't the error method work on a udt array?
-
Jul 6th, 2007, 09:43 PM
#10
Re: [RESOLVED] Best way to determine # of array dimensions?
Compile Error:
Only user-defined types defined in public object modules can be coerced to or from a variant or passed to late-bound functions.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|