Die Übergabe eines nicht dimensionierten Arrays an die Ubound-Funktion von VB6 führt zu einem Fehler. Ich möchte also überprüfen, ob das Array bereits dimensioniert wurde, bevor ich versuche, seine obere Grenze zu überprüfen. Wie kann ich dies tun?
Antworten
Zu viele Anzeigen?Es sind zwei leicht unterschiedliche Szenarien zu testen:
- Das Array wird initialisiert (es handelt sich also nicht um einen Null-Zeiger)
- Das Array ist initialisiert und hat mindestens ein Element
Fall 2 ist erforderlich für Fälle wie Split(vbNullString, ",")
die eine String
Array mit LBound=0
y UBound=-1
. Hier sind die einfachsten Beispielcodeausschnitte, die ich für jeden Test erstellen kann:
Public Function IsInitialised(arr() As String) As Boolean
On Error Resume Next
IsInitialised = UBound(arr) <> 0.5
End Function
Public Function IsInitialisedAndHasElements(arr() As String) As Boolean
On Error Resume Next
IsInitialisedAndHasElements = UBound(arr) >= LBound(arr)
End Function
Sie können das Problem lösen mit Ubound()
Funktion, prüfen Sie, ob das Array leer ist, indem Sie die Gesamtzahl der Elemente mit JScripts VBArray()
Objekt (funktioniert mit Arrays unterschiedlichen Typs, ein- oder mehrdimensional):
Sub Test()
Dim a() As Variant
Dim b As Variant
Dim c As Long
' Uninitialized array of variant
' MsgBox UBound(a) ' gives 'Subscript out of range' error
MsgBox GetElementsCount(a) ' 0
' Variant containing an empty array
b = Array()
MsgBox GetElementsCount(b) ' 0
' Any other types, eg Long or not Variant type arrays
MsgBox GetElementsCount(c) ' -1
End Sub
Function GetElementsCount(aSample) As Long
Static oHtmlfile As Object ' instantiate once
If oHtmlfile Is Nothing Then
Set oHtmlfile = CreateObject("htmlfile")
oHtmlfile.parentWindow.execScript ("function arrlength(arr) {try {return (new VBArray(arr)).toArray().length} catch(e) {return -1}}"), "jscript"
End If
GetElementsCount = oHtmlfile.parentWindow.arrlength(aSample)
End Function
Für mich dauert es etwa 0,4 mksec für jedes Element + 100 msec Initialisierung, mit VB 6.0.9782 kompiliert, so dass das Array von 10M Elemente dauert etwa 4,1 sec. Die gleiche Funktionalität könnte implementiert werden über ScriptControl
ActiveX.
Mein einziges Problem mit API-Aufrufen ist der Wechsel von 32-Bit- zu 64-Bit-Betriebssystemen.
Dies funktioniert mit Objekten, Strings, etc...
Public Function ArrayIsInitialized(ByRef arr As Variant) As Boolean
On Error Resume Next
ArrayIsInitialized = False
If UBound(arr) >= 0 Then If Err.Number = 0 Then ArrayIsInitialized = True
End Function