it-swarm.com.de

Überprüfen, ob ein Array im VBA-Makro leer ist

Ich möchte nach leeren Arrays suchen. Google gab mir verschiedene Lösungen, aber nichts hat funktioniert. Vielleicht wende ich sie nicht richtig an.

Function GetBoiler(ByVal sFile As String) As String
'Email Signature
    Dim fso As Object
    Dim ts As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set ts = fso.GetFile(sFile).OpenAsTextStream(1, -2)
    GetBoiler = ts.ReadAll
    ts.Close
End Function

Dim FileNamesList As Variant, i As Integer
' activate the desired startfolder for the filesearch
FileNamesList = CreateFileList("*.*", False) ' Returns File names
' performs the filesearch, includes any subfolders
' present the result
' If there are Signatures then populate SigString
Range("A:A").ClearContents
For i = 1 To UBound(FileNamesList)
    Cells(i + 1, 1).Formula = FileNamesList(i)
Next i

SigString = FileNamesList(3)

If Dir(SigString) <> "" Then
    Signature = GetBoiler(SigString)
Else
    Signature = ""
End If

Hier sollte, wenn das Array FileNamesList leer ist, GetBoiler(SigString) überhaupt nicht aufgerufen werden. Wenn das Array FileNamesList leer ist, ist auch SigString leer, und dies ruft die Funktion GetBoiler() mit einer leeren Zeichenfolge auf. Ich erhalte einen Fehler in der Zeile

Set ts = fso.GetFile(sFile).OpenAsTextStream(1, -2)

da sFile leer ist. Wie kann man das vermeiden?

56
Vicky

Haben Sie bei der Bearbeitung eines String-Arrays über Join nachgedacht?

If Len(Join(FileNamesList)) > 0 Then
73
Fionnuala

Gehen Sie mit einem dreifachen Negativ:

If (Not Not FileNamesList) <> 0 Then
    ' Array has been initialized, so you're good to go.
Else
    ' Array has NOT been initialized
End If

Oder nur:

If (Not FileNamesList) = -1 Then
    ' Array has NOT been initialized
Else
    ' Array has been initialized, so you're good to go.
End If

In VB, aus welchem ​​Grund auch immer, Not myArray gibt den SafeArray-Zeiger zurück. Für nicht initialisierte Arrays wird -1 zurückgegeben. Sie können dies mit -1 Not zu XOR=) und damit, wenn Sie es vorziehen, Null zurückgeben.

               (Not myArray)   (Not Not myArray)
Uninitialized       -1                 0
Initialized    -someBigNumber   someOtherBigNumber

Quelle

62
ahuth

Wenn Sie eine Array-Funktion testen, funktioniert dies für alle Grenzen:

Function IsVarArrayEmpty(anArray As Variant)

Dim i As Integer

On Error Resume Next
    i = UBound(anArray,1)
If Err.number = 0 Then
    IsVarArrayEmpty = False
Else
    IsVarArrayEmpty = True
End If

End Function
28
Lance Roberts

Ich sehe ähnliche Antworten hier ... aber nicht meine ...

Dies ist, wie ich leider damit umgehen werde ... Ich mag den Ansatz len (join (arr))> 0, aber es würde nicht funktionieren, wenn das Array ein Array von leeren Ringen wäre ...

Public Function arrayLength(arr As Variant) As Long
  On Error GoTo handler

  Dim lngLower As Long
  Dim lngUpper As Long

  lngLower = LBound(arr)
  lngUpper = UBound(arr)

  arrayLength = (lngUpper - lngLower) + 1
  Exit Function

handler:
  arrayLength = 0 'error occured.  must be zero length
End Function
6
Perposterer

Beim Schreiben von VBA steht dieser Satz in meinem Kopf: "Könnte so einfach sein, aber ..."

Hier ist, worauf ich es angewendet habe:

Private Function IsArrayEmpty(arr As Variant)
  ' This function returns true if array is empty
  Dim l As Long

  On Error Resume Next
  l = Len(Join(arr))
  If l = 0 Then
    IsArrayEmpty = True
  Else
    IsArrayEmpty = False
  End If

  If Err.Number > 0 Then
      IsArrayEmpty = True
  End If

  On Error GoTo 0
End Function

Private Sub IsArrayEmptyTest()
  Dim a As Variant
  a = Array()
  Debug.Print "Array is Empty is " & IsArrayEmpty(a)
  If IsArrayEmpty(a) = False Then
    Debug.Print "  " & Join(a)
  End If
End Sub
5
BBQ Chef

Dieser Code entspricht nicht Ihren Erwartungen:

If Dir(SigString) <> "" Then
    Signature = GetBoiler(SigString) 
Else
    Signature = "" 
End If

Übergeben Sie eine leere Zeichenfolge ("") oder vbNullString bis Dir wird der Name der ersten Datei im aktuellen Verzeichnispfad zurückgegeben (der Pfad, der von CurDir$). Wenn also SigString leer ist, wird Ihre If -Bedingung zu True ausgewertet, da Dir eine nicht leere Zeichenfolge (den Namen der ersten Datei) zurückgibt im aktuellen Verzeichnis) und GetBoiler werden aufgerufen. Und wenn SigString leer ist, wird der Aufruf von fso.GetFile wird versagen.

Sie sollten entweder Ihre Bedingung ändern, um sicherzustellen, dass SigString nicht leer ist, oder das FileSystemObject.FileExists Methode anstelle von Dir um zu prüfen, ob die Datei existiert. Dir ist schwierig zu verwenden, weil es Dinge tut, die Sie vielleicht nicht erwarten. Persönlich würde ich Scripting.FileSystemObject über Dir, weil es keine lustige Sache gibt (FileExists gibt True zurück, wenn die Datei existiert, und False, wenn sie nicht existiert). Außerdem drückt FileExists die Absicht Ihres Codes viel deutlicher aus als Dir.

Methode 1: Überprüfen Sie zuerst, ob SigString nicht leer ist

If SigString <> "" And Dir(SigString) <> "" Then
    Signature = GetBoiler(SigString) 
Else
    Signature = "" 
End If

Methode 2: Verwenden Sie die FileSystemObject.FileExists Methode

Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")

If fso.FileExists(SigString) Then
    Signature = GetBoiler(SigString) 
Else
    Signature = "" 
End If
4
Mike Spross

Ich füge einfach den Code des großartigen Chips Pearson ein. Es wirkt wie ein Zauber.
Hier ist sein Seite über Array-Funktionen .

Ich hoffe das hilft.

Public Function IsArrayEmpty(Arr As Variant) As Boolean
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' IsArrayEmpty
' This function tests whether the array is empty (unallocated). Returns TRUE or FALSE.
'
' The VBA IsArray function indicates whether a variable is an array, but it does not
' distinguish between allocated and unallocated arrays. It will return TRUE for both
' allocated and unallocated arrays. This function tests whether the array has actually
' been allocated.
'
' This function is really the reverse of IsArrayAllocated.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    Dim LB As Long
    Dim UB As Long

    err.Clear
    On Error Resume Next
    If IsArray(Arr) = False Then
        ' we weren't passed an array, return True
        IsArrayEmpty = True
    End If

    ' Attempt to get the UBound of the array. If the array is
    ' unallocated, an error will occur.
    UB = UBound(Arr, 1)
    If (err.Number <> 0) Then
        IsArrayEmpty = True
    Else
        ''''''''''''''''''''''''''''''''''''''''''
        ' On rare occasion, under circumstances I
        ' cannot reliably replicate, Err.Number
        ' will be 0 for an unallocated, empty array.
        ' On these occasions, LBound is 0 and
        ' UBound is -1.
        ' To accommodate the weird behavior, test to
        ' see if LB > UB. If so, the array is not
        ' allocated.
        ''''''''''''''''''''''''''''''''''''''''''
        err.Clear
        LB = LBound(Arr)
        If LB > UB Then
            IsArrayEmpty = True
        Else
            IsArrayEmpty = False
        End If
    End If

End Function
4
sancho.s

Auth war am nächsten, aber seine Antwort wirft einen Typenkonfliktfehler auf.

Bei den anderen Antworten sollten Sie es vermeiden, einen Fehler zu verwenden, um eine Bedingung zu testen, sofern dies möglich ist, da dies zumindest das Debuggen erschwert (was passiert, wenn dieser Fehler durch etwas anderes verursacht wird).

Hier ist eine einfache, vollständige Lösung:

option explicit
Function foo() As Variant

    Dim bar() As String

    If (Not Not bar) Then
        ReDim Preserve bar(0 To UBound(bar) + 1)
    Else
        ReDim Preserve bar(0 To 0)
    End If

    bar(UBound(bar)) = "it works!"

    foo = bar

End Function
2
Mike Bethany

Vereinfachte Überprüfung für leeres Array:

Dim exampleArray() As Variant 'Any Type

If ((Not Not exampleArray) = 0) Then
      'Array is Empty
Else
      'Array is Not Empty
End If
2
Robert S.

Basierend auf Ahuths Antwort ;

Function AryLen(ary() As Variant, Optional idx_dim As Long = 1) As Long
    If (Not ary) = -1 Then
        AryLen = 0
    Else
        AryLen = UBound(ary, idx_dim) - LBound(ary, idx_dim) + 1
    End If
End Function

Suchen Sie nach einem leeren Array. is_empty = AryLen(some_array)=0

2
user425678

Um zu überprüfen, ob ein Byte-Array leer ist, verwenden Sie am einfachsten die VBA-Funktion StrPtr().

Wenn das Byte-Array leer ist, gibt StrPtr()0 Zurück; Andernfalls wird ein Wert ungleich Null zurückgegeben (dies ist jedoch der Fall nicht die Adresse zum ersten Element).

Dim ar() As Byte
Debug.Assert StrPtr(ar) = 0

ReDim ar(0 to 3) As Byte
Debug.Assert StrPtr(ar) <> 0

Es funktioniert jedoch nur mit Byte-Array.

1
Fuzzier

Eine andere Methode wäre, es früher zu tun. Sie können eine boolesche Variable erstellen und auf true setzen, sobald Sie Daten in das Array laden. Alles, was Sie wirklich brauchen, ist eine einfache if-Anweisung, die angibt, wann Sie Daten in das Array laden.

1
Tim Boutchia
Public Function IsEmptyArray(InputArray As Variant) As Boolean

   On Error GoTo ErrHandler:
   IsEmptyArray = Not (UBound(InputArray) >= 0)
   Exit Function

   ErrHandler:
   IsEmptyArray = True

End Function
1
Zhenya

Hier ist eine andere Möglichkeit, dies zu tun. Ich habe es in einigen Fällen verwendet und es funktioniert.

Function IsArrayEmpty(arr As Variant) As Boolean

Dim index As Integer

index = -1
    On Error Resume Next
        index = UBound(arr)
    On Error GoTo 0

If (index = -1) Then IsArrayEmpty = True Else IsArrayEmpty = False

End Function
1
Surya
Function IsVarArrayEmpty(anArray As Variant) as boolean
    On Error Resume Next
    IsVarArrayEmpty = true
    IsVarArrayEmpty = UBound(anArray) < LBound(anArray)
End Function

Vielleicht stürzt ubound ab und es bleibt wahr, und wenn ubound < lbound, es ist leer

1
Pierre

Sie können die Anzahl überprüfen.

Hier cid ist ein Array.

if (jsonObject("result")("cid").Count) = 0 them
MsgBox "Empty Array"

Ich hoffe das hilft. Einen schönen Tag noch!

0
Mantej Singh

Sie können überprüfen, ob das Array leer ist, indem Sie die Gesamtzahl der Elemente mit dem Objekt VBArray() von JScript abrufen (funktioniert mit ein- oder mehrdimensionalen Arrays des Variantentyps):

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 ungefähr 0,3 mksec für jedes Element + 15 msec Initialisierung, also dauert das Array von 10M Elementen ungefähr 3 sec. Dieselbe Funktionalität könnte über ScriptControl ActiveX implementiert werden (es ist in 64-Bit-Versionen von MS Office nicht verfügbar, daher können Sie eine Problemumgehung wie this verwenden.).

0
omegastripes
if Ubound(yourArray)>-1 then
 debug.print "The array is not empty"
else
 debug.print "EMPTY"
end if
0
Dave Poole

Ich werde das Problem und die Frage wie beabsichtigt verallgemeinern. Testen Sie die Zuordnung auf dem Array, und stellen Sie den eventuellen Fehler fest

Function IsVarArrayEmpty(anArray as Variant)
Dim aVar as Variant

IsVarArrayEmpty=False
On error resume next
aVar=anArray(1)
If Err.number then '...still, it might not start at this index
    aVar=anArray(0)
    If Err.number then IsVarArrayEmpty=True ' neither 0 or 1 yields good assignment
EndIF
End Function

Sicher, es fehlen Arrays mit allen negativen Indizes oder allen> 1 ... ist das wahrscheinlich? In Weirdland, ja.

0
jpinto3912

Persönlich denke ich, dass eine der Antworten oben geändert werden kann, um zu überprüfen, ob das Array Inhalt hat:

if UBound(ar) > LBound(ar) Then

Dies verarbeitet Verweise auf negative Zahlen und nimmt weniger Zeit in Anspruch als einige der anderen Optionen.

0
Jim Snyder

Sie können die folgende Funktion verwenden, um zu überprüfen, ob die Variante oder das String-Array in vba leer ist

Function IsArrayAllocated(Arr As Variant) As Boolean
        On Error Resume Next
        IsArrayAllocated = IsArray(Arr) And _
                           Not IsError(LBound(Arr, 1)) And _
                           LBound(Arr, 1) <= UBound(Arr, 1)
End Function

Beispielnutzung

Public Function test()
Dim Arr(1) As String
Arr(0) = "d"
Dim x As Boolean
x = IsArrayAllocated(Arr)
End Function
0