Hi,
The easiest way is to use UBound and trap the error you'll get if it
hasen't been dimensioned.
Alternatively, I found this code and did a quick test with access 97 and immediately
got a page fault. I'll post it though and you can troubleshoot it if you like: (watch out for line wrap)
This will go in a standard module:
Option Compare Database
Option Explicit
Type SAFEARRAYBOUND
cElements As Long ' # of elements in the array dimension
lLbound As Long ' lower bounds of the array dimension
End Type
Public Type SAFEARRAY
cDims As Integer ' // Count of dimensions in this array.
fFeatures As Integer ' // Flags used by the SafeArray
' // routines documented below.
cbElements As Long ' // Size of an element of the array.
' // Does not include size of
' // pointed-to data.
cLocks As Long ' // Number of times the array has been
' // locked without corresponding unlock.
pvData As Long ' // Pointer to the data.
' Should be sized to cDims:
rgsabound() As SAFEARRAYBOUND ' // One bound for each dimension.
End Type
Const VT_BYREF = &H4000&
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long)
Public Function GetArrayInfo(TheArray As Variant, ArrayInfo As SAFEARRAY) As Boolean
Dim lp As Long, VType As Integer
If Not IsArray(TheArray) Then Exit Function
With ArrayInfo
' Get the VARTYPE value from the first 2 bytes of the VARIANT structure
CopyMemory ByVal VarPtr(VType), ByVal VarPtr(TheArray), 2
' Get the pointer to the array descriptor (SAFEARRAY structure)
' NOTE: A Variant's descriptor, padding & union take up 8 bytes.
CopyMemory ByVal VarPtr(lp), ByVal (VarPtr(TheArray) + 8), 4
' Test if lp is a pointer or a pointer to a pointer.
If (VType And VT_BYREF) <> 0 Then
' Get real pointer to the array descriptor (SAFEARRAY structure)
CopyMemory ByVal VarPtr(lp), ByVal lp, 4
End If
' Fill the SAFEARRAY structure with the array info
' NOTE: The fixed part of the SAFEARRAY structure is 16 bytes.
CopyMemory ByVal VarPtr(ArrayInfo.cDims), ByVal lp, 16
' Ensure the array has been dimensioned before getting SAFEARRAYBOUND information
If ArrayInfo.cDims > 0 Then
' Size the array to fit the # of bounds
ReDim .rgsabound(1 To .cDims)
' Fill the SAFEARRAYBOUND structure with the array info
CopyMemory ByVal VarPtr(.rgsabound(1)), ByVal lp + 16, ArrayInfo.cDims * Len(.rgsabound(1))
' So caller knows there is information available for the array in output SAFEARRAY
GetArrayInfo = True
End If
End With
End Function
And this could go in your form:
Private Sub cmdArray_Click()
Dim sa As SAFEARRAY
Dim myArr() As Variant
If GetArrayInfo(arr, sa) Then
MsgBox "Array have " & sa.cDims & " dimensions."
Else
MsgBox "Array not dimensioned yet"
End If
End Sub
Good luck!