VBA check if array is one dimensional

后端 未结 5 1687
我寻月下人不归
我寻月下人不归 2020-12-08 12:01

I have an array (that comes from SQL) and can potentially have one or more rows.

I want to be able to figure out if the array has just one row.

UBound doesn\

5条回答
  •  时光取名叫无心
    2020-12-08 12:54

    I found Blackhawks's accepted and revised answer very instructive, so I played around with it and learned some useful things from it. Here's a slightly modified version of that code that includes a test sub at the bottom.

    Option Explicit
    
    Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" ( _
        ByVal Destination As Long, ByVal Source As Long, ByVal Length As Integer)
    
    Public Function GetDims(VarSafeArray As Variant) As Integer
        Dim variantType As Integer
        Dim pointer As Long
        Dim arrayDims As Integer
    
        'The first 2 bytes of the VARIANT structure contain the type:
        CopyMemory VarPtr(variantType), VarPtr(VarSafeArray), 2&
    
        If Not (variantType And &H2000) > 0 Then
        'It's not an array. Raise type mismatch.
            Err.Raise (13)
        End If
    
        'If the Variant contains an array or ByRef array, a pointer for the _
            SAFEARRAY or array ByRef variant is located at VarPtr(VarSafeArray) + 8:
        CopyMemory VarPtr(pointer), VarPtr(VarSafeArray) + 8, 4&
    
        'If the array is ByRef, there is an additional layer of indirection through_
        'another Variant (this is what allows ByRef calls to modify the calling scope).
        'Thus it must be dereferenced to get the SAFEARRAY structure:
        If (variantType And &H4000) > 0 Then 'ByRef (&H4000)
            'dereference the pointer to pointer to get actual pointer to the SAFEARRAY
            CopyMemory VarPtr(pointer), pointer, 4&
        End If
        'The pointer will be 0 if the array hasn't been initialized
        If Not pointer = 0 Then
            'If it HAS been initialized, we can pull the number of dimensions directly _
                from the pointer, since it's the first member in the SAFEARRAY struct:
            CopyMemory VarPtr(arrayDims), pointer, 2&
            GetDims = arrayDims
        Else
            GetDims = 0 'Array not initialized
        End If
    End Function
    
    Sub TestGetDims()
    ' Tests GetDims(). Should produce the following output to Immediate Window:
    '
    ' 1             One
    ' 2             Two
    ' Number of array dimensions: 2
    
        Dim myArray(2, 2) As Variant
        Dim iResult As Integer
        myArray(0, 0) = 1
        myArray(1, 0) = "One"
        myArray(0, 1) = 2
        myArray(1, 1) = "Two"
    
        Debug.Print myArray(0, 0), myArray(1, 0)
        Debug.Print myArray(0, 1), myArray(1, 1)
    
        iResult = GetDims(myArray)
    
        Debug.Print "Number of array dimensions: " & iResult
    End Sub
    

提交回复
热议问题