VB bietet mit der
UBound-Funktion eine Möglichkeit an, die
Größe einer Array-Dimension zu bestimmen. Die
Anzahl der Dimensionen kann leider nicht so einfach bestimmt werden. Entweder man versucht sein Glück mit einem Error-Handler, oder man greift mal wieder auf eine API-Funktion zurück. Dazu muss man allerdings folgendes über die Verwaltung von VB-Feldern wissen:
- Eine Variant-Variable (wird für die Übergabe an unsere Funktion benutzt) enthält intern u.a. eine Angabe zum Datentyp. Handelt es sich um ein Array, dann enthält sie auch einen Zeiger auf ein VB-Array (Offset: 8 Bytes).
- Ein VB-Array ist intern nur ein Zeiger auf einen sogenannten SafeArrayDescriptor.
- Dieser Deskriptor enthält u.a. einen Zeiger auf eine sogenannte SafeArray-Struktur.
- Diese Struktur endlich beschreibt u.a. die Lage der Daten sowie die Dimensionierung des Feldes. Die Anzahl der Dimensionen steht gleich am Anfang (2 Bytes).
Beispiel
Dim a() As String
Dim b(2 To 8) As Long
Dim c(8, 7, 6) As Byte
MsgBox Dimension(a) 'ergibt 0
MsgBox Dimension(b) 'ergibt 1
MsgBox Dimension(c) 'ergibt 3
Code
Im Deklarationsteil des Moduls wird die immer wieder gerne verwendete API-Routine
RtlMoveMemory zur Verfügung gestellt, welche Speicherbereiche kopieren kann:
Private Declare Sub RtlMoveMemory Lib "kernel32" ( _
dest As Any, source As Any, ByVal bytes As Long)
Die eigentliche Funktion erwartet ein Array als Parameter (ansonsten wird eine entsprechende Fehler-Meldung generiert):
Function Dimension(ByRef Variable As Variant) As Integer
Dim Ptr As Long
If IsArray(Variable) Then
Ptr = VarPtr(Variable) + 8 'VB-Array
RtlMoveMemory Ptr, ByVal Ptr, 4 'SafeArrayDescriptor
RtlMoveMemory Ptr, ByVal Ptr, 4 'SafeArray-Struktur
If Ptr Then RtlMoveMemory Dimension, ByVal Ptr, 2
Else
Err.Raise 13 'Type mismatch
End If
End Function