Results 1 to 10 of 10

Thread: [RESOLVED] Best way to determine # of array dimensions?

  1. #1

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Resolved [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:
    1. Sub Test()
    2.     Dim varArray As Variant
    3.     Dim lngArray() As Long
    4.    
    5.     Debug.Print ArrayDimensions(varArray) & "," & ArrayDimensions(lngArray)
    6.     ReDim varArray(9)
    7.     ReDim lngArray(9)
    8.     Debug.Print ArrayDimensions(varArray) & "," & ArrayDimensions(lngArray)
    9.     ReDim varArray(9,9)
    10.     ReDim lngArray(9,9)
    11.     Debug.Print ArrayDimensions(varArray) & "," & ArrayDimensions(lngArray)
    12.     Erase varArray, lngArray
    13.     Debug.Print ArrayDimensions(varArray) & "," & ArrayDimensions(lngArray)
    14. End Sub
    15.  
    16. Function ArrayDimensions(pvarArray As Variant) As Long
    17.     ' ???
    18. End Function
    Which would ideally look like this in the debug window:

    Test
    0,0
    1,1
    2,2
    0,0

    Any ideas?

  2. #2
    PowerPoster
    Join Date
    Nov 2002
    Location
    Manila
    Posts
    7,629

    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.

  3. #3
    Frenzied Member
    Join Date
    Jun 2006
    Posts
    1,098

    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

  4. #4

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    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:
    1. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    2.  
    3. Public Function ArrayDimensions(pvarArray As Variant) As Long
    4.     Dim lngPointer As Long ' ???
    5.    
    6.     If VarType(pvarArray) < vbArray Then
    7.         ArrayDimensions = -1
    8.     Else
    9.         CopyMemory lngPointer, pvarArray, 4 ' ???
    10.     End If
    11. 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?

  5. #5
    coder. Lord Orwell's Avatar
    Join Date
    Feb 2001
    Location
    Elberfeld, IN
    Posts
    7,628

    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.
    My light show youtube page (it's made the news) www.youtube.com/@lightsofelberfeld
    Contact me on the socials www.facebook.com/lordorwell

  6. #6
    Interweb adm/o/distrator Paul M's Avatar
    Join Date
    Nov 2006
    Location
    Australia, Melbourne
    Posts
    2,306

    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

  7. #7
    Interweb adm/o/distrator Paul M's Avatar
    Join Date
    Nov 2006
    Location
    Australia, Melbourne
    Posts
    2,306

    Re: Best way to determine # of array dimensions?

    Dimensions of Array

    The method there uses the CopyMemory API and it works very well

  8. #8

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    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.

  9. #9
    coder. Lord Orwell's Avatar
    Join Date
    Feb 2001
    Location
    Elberfeld, IN
    Posts
    7,628

    Re: [RESOLVED] Best way to determine # of array dimensions?

    why wouldn't the error method work on a udt array?
    My light show youtube page (it's made the news) www.youtube.com/@lightsofelberfeld
    Contact me on the socials www.facebook.com/lordorwell

  10. #10

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    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
  •  



Click Here to Expand Forum to Full Width