VBA check if array is one dimensional

后端 未结 5 1701
我寻月下人不归
我寻月下人不归 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:35

    I realized that my original answer can be simplified - rather than having the VARIANT and SAFEARRAY structures defined as VBA Types, all that is needed is a few CopyMemorys to get the pointers and finally the Integer result.

    Here is the simplest complete GetDims that checks the dimensions directly through the variables in memory:

    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
    
        CopyMemory VarPtr(variantType), VarPtr(VarSafeArray), 2& 'the first 2 bytes of the VARIANT structure contain the type
    
        If (variantType And &H2000) > 0 Then 'Array (&H2000)
            '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 the 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
        Else
            GetDims = 0 'It's not an array... Type mismatch maybe?
        End If
    End Function
    

提交回复
热议问题