|
Sie können der Array-Funktion in Visual Basic eine Liste von beliebigen Werten oder Objekten übergeben, und sie gibt Ihnen ein aus diesen Werten gebildetes Variant-Array zurück:
Dim nArray As Variant
nArray = Array(1, "Hallo", Now, Nothing)
So praktisch diese Funktion auch ist - datentypsicher ist sie jedoch nicht. Wenn Sie dagegen Wert auf Typsicherheit legen, ist es ein Leichtes, eigene Varianten dieser Funktion zu erstellen. In diesen können Sie sowohl die einzelnen übergebenen Elemente der Parameterliste auf den Datentyp hin prüfen lassen als auch das zurückgegebene Array als bestimmten Datentyp deklarieren.
Public Function ArrayStr(ParamArray Items() As Variant) _
As String()
Dim l As Long
Dim nArrayStr() As String
ReDim nArrayStr(0 To UBound(Items))
For l = 0 To UBound(Items)
nArrayStr(l) = Items(l)
Next 'l
ArrayStr = nArrayStr
End Function
Sind Sie nach einem ersten Blick auf den Code dieser Funktion der Meinung, dass sie (wie erwartet) andere Datentypen als String mit einer Fehlermeldung zurückweisen wird? Na, wenn ich schon so scheinheilig frage, wird sie das bestimmt nicht tun. Die automatische Typkonvertierung von Visual Basic macht uns hier nämlich einen Strich durch die Rechnung. Denn alle Werte, die sich in einen String konvertieren lassen , werden akzeptiert. Genauer gesagt: Alle Werte, die einen String repräsentieren, werden akzeptiert - das schließt nämlich sogar Objekte ein, deren Standard-Eigenschaft einen in einen String konvertierbaren Wert zurückgibt.
Es hilft nichts - Sie müssen schon den gewünschten Datentyp (hier: String) ausdrücklich untersuchen und unpassende Werte zurückweisen:
Public Const gInvalidParamType = 30000
Private Const kInvalidParamType = _
"Ungültiger Datentyp - Parameter Nr. "
Public Function ArrayStr(ParamArray Items() As Variant) As String()
Dim l As Long
Dim nArrayStr() As String
ReDim nArrayStr(0 To UBound(Items))
For l = 0 To UBound(Items)
Hier folgen die Prüfung des Datentyps:
If VarType(Items(l)) = vbString Then
nArrayStr(l) = Items(l)
Else
und die "komfortable" Fehlermeldung mit Angabe, an welcher Stelle das (erste) unpassende Element auftaucht:
Err.Raise gInvalidParamType, , _
kInvalidParamType & l + 1 & " - " & TypeName(Items(l))
End If
Next 'l
ArrayStr = nArrayStr
End Function
Wenn Ihnen diese Festlegung nun doch etwas zu strikt sein sollte, können Sie auch erst zur Laufzeit zumindest den Datentyp der übergebenen Elemente festlegen. Den Datentyp des zurückgegebenen Arrays können Sie dann allerdings nicht mehr festlegen. Die erste Möglichkeit für die wahlfreie Datentyp-Festlegung besteht darin, den Datentyp zusätzlich als Parameter zu übergeben, und ein Variant-Array zu erhalten:
Public Function ArrayTyped(VariantType As VbVarType, _
ParamArray Items() As Variant) As Variant
Dim l As Long
Dim nArray() As Variant
ReDim nArray(0 To UBound(Items))
For l = 0 To UBound(Items)
If VarType(Items(l)) = VariantType Then
nArray(l) = Items(l)
Else
Err.Raise gInvalidParamType, , _
kInvalidParamType & l + 1 & " - " & TypeName(Items(l))
End If
Next 'l
ArrayTyped = nArray
End Function
Der kleine Nachteil dieser Funktion besteht darin, dass Sie zwar zwischen den verschiedenen Grunddatentypen unterscheiden können, Objekte jedoch alle in einen Topf geworfen werden (Datentyp vbObject).
Die folgende Variante bügelt auch dieses Problem weg - allerdings ist sie ein wenig langsamer wegen der String-Verarbeitung. Ihr übergeben Sie nämlich den Typnamen als String:
Public Function ArrayNamed(Name As String, _
ParamArray Items() As Variant) As Variant
Dim l As Long
Dim nArray() As Variant
ReDim nArray(0 To UBound(Items))
For l = 0 To UBound(Items)
If TypeName(Items(l)) = Name Then
If IsObject(Items(l)) Then
Set nArray(l) = Items(l)
Else
nArray(l) = Items(l)
End If
Else
Err.Raise gInvalidParamType, , _
kInvalidParamType & l + 1 & " - " & TypeName(Items(l))
End If
Next 'l
ArrayNamed = nArray
End Function
Ist Ihnen dies nun schon wieder zu flexibel für Objekte? Nun, Sie können es bei Objekten auch wieder restriktiver handhaben - zum Beispiel für eine Klasse namens "Class1". Hier pfuscht uns die automatische Typkonvertierung nicht ins Handwerk, so dass wir uns auf die strikte Zuweisung verlassen können:
Public Function ArrayClass1(ParamArray Items() As Variant) _
As Class1()
Dim l As Long
Dim nArray() As Class1
On Error Resume Next
ReDim nArray(0 To UBound(Items))
For l = 0 To UBound(Items)
Set nArray(l) = Items(l)
If Err.Number Then
Err.Raise gInvalidParamType, , _
kInvalidParamType & l + 1 & " - " & TypeName(Items(l))
End If
Next 'l
ArrayClass1 = nArray
End Function
|