/ / So suchen Sie im vba-Makro nach leeren Arrays - excel, vba, excel-vba

So suchen Sie im vba-Makro nach leeren Arrays - excel, vba, excel-vba

Ich möchte nach leeren Arrays suchen. Google hat mir verschiedene Lösungen gegeben, 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, wenn FileNamesList Array ist leer, GetBoiler(SigString) sollte überhaupt nicht angerufen werden. Wann FileNamesList Array ist leer, SigString ist auch leer und das ruft GetBoiler() Funktion mit leerer Zeichenfolge. Ich erhalte einen Fehler in der Leitung

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

schon seit sFile ist leer. Wie kann man das vermeiden?

Antworten:

66 für die Antwort № 1

Haben Sie beim Umgang mit einem String-Array über Join nachgedacht?

If Len(Join(FileNamesList)) > 0 Then

44 für die Antwort № 2

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. Bei nicht initialisierten Arrays wird -1 zurückgegeben. Du kannst Not dies zu XOR es mit -1, so dass Null zurückgegeben wird, wenn Sie es vorziehen.

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

Quelle


26 für die Antwort № 3

Wenn Sie eine Array-Funktion testen, funktioniert sie 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

6 für die Antwort № 4

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

So werde ich leider damit umgehen ... Ich mag den Ansatz len (join (arr))> 0, aber es würde nicht funktionieren, wenn das Array ein Array von Emptystrings 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

5 für die Antwort № 5

Beim Schreiben von VBA gibt es diesen Satz in meinem Kopf: "Könnte so einfach sein, aber ..."

Folgendes habe ich übernommen:

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

4 für die Antwort № 6

Dieser Code macht nicht das, was Sie erwarten:

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

Wenn Sie eine leere Zeichenfolge übergeben ("") oder vbNullString zu Dirgibt den Namen der ersten Datei im aktuellen Verzeichnispfad zurück (den von zurückgegebenen Pfad CurDir$). Also, wenn SigString ist leer, dein If Zustand wird ausgewertet True weil Dir gibt eine nicht leere Zeichenfolge zurück (den Namen der ersten Datei im aktuellen Verzeichnis) und GetBoiler wird angerufen werden. Und wenn SigString ist leer, der anruf fso.GetFile wird versagen.

Sie sollten entweder Ihren Zustand ändern, um dies zu überprüfen SigString ist nicht leer, oder verwenden Sie die FileSystemObject.FileExists Methode statt Dir um zu überprüfen, ob die Datei vorhanden ist. Dir Es ist schwierig, genau deshalb zu verwenden, weil es Dinge tut, die Sie vielleicht nicht erwarten. Persönlich würde ich verwenden Scripting.FileSystemObject Über Dir weil es kein lustiges Geschäft gibt (FileExists kehrt zurück True wenn die Datei existiert, und nun, False wenn es nicht "t). Was ist mehr, FileExists drückt die aus Absicht Ihres Codes viel klarer als Dir.

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

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 für die Antwort № 7

Ich füge einfach unter den Code des großen Chip Pearson ein. Es wirkt 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

2 für die Antwort № 8

Auth war am nächsten, aber seine Antwort löst einen Typ-Mismatch-Fehler aus.

Was die anderen Antworten betrifft, sollten Sie es vermeiden, einen Fehler zum Testen einer Bedingung zu verwenden, wenn Sie können, da dies zumindest das Debuggen erschwert (was ist, wenn etwas anderes diesen Fehler verursacht).

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 für die Antwort № 9

Vereinfachte Prüfung auf 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 für die Antwort № 10

Basierend auf ahuth "s Antworten;

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


1 für die Antwort № 11
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 für die Antwort № 12

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, wann Sie Daten in das Array laden.


1 für die Antwort № 13

Hier ist eine andere Möglichkeit, dies zu tun. Ich habe es in einigen Fällen benutzt 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 für die Antwort № 14

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

Wenn das Byte-Array leer ist, StrPtr() kehrt zurück 0;; Andernfalls wird ein Wert ungleich Null zurückgegeben (es ist jedoch "s") 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.


0 für die Antwort № 15

Ich werde das Problem und die Frage wie beabsichtigt verallgemeinern. Testen Sie die Bewertung auf dem Array und ermitteln Sie den eventuellen Fehler

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 für die Antwort № 16

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

if UBound(ar) > LBound(ar) Then

Dies verarbeitet negative Zahlenreferenzen und benötigt weniger Zeit als einige der anderen Optionen.


0 für die Antwort № 17

Mit der folgenden Funktion können Sie ü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

Verwendungsbeispiel

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

0 für die Antwort № 18

Sie können überprüfen, ob das Array leer ist, indem Sie die Gesamtzahl der Elemente mithilfe von JScript abrufen VBArray() Objekt (funktioniert mit Arrays vom Variantentyp, 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 ungefähr 0,3 mksec für jedes Element + 15 ms Initialisierung, also dauert das Array von 10M Elementen ungefähr 3 s. Die gleiche Funktionalität könnte über implementiert werden ScriptControl ActiveX (ist in 64-Bit-MS Office-Versionen nicht verfügbar, sodass Sie eine Problemumgehung wie verwenden können Dies).


0 für die Antwort № 19
if Ubound(yourArray)>-1 then
debug.print "The array is not empty"
else
debug.print "EMPTY"
end if

0 für die Antwort № 20
Function IsVarArrayEmpty(anArray As Variant) as boolean
On Error Resume Next
IsVarArrayEmpty = true
IsVarArrayEmpty = UBound(anArray) < LBound(anArray)
End Function

Könnte sein ubound stürzt ab und es bleibt wahr, und wenn ubound < lbound, es ist leer


0 für die Antwort № 21

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!


-1 für die Antwort № 22

Eine weitere Lösung zum Testen auf leeres Array

if UBound(ar) < LBound(ar) then msgbox "Your array is empty!"

Oder wenn Sie bereits wissen, dass LBound 0 ist

if -1 = UBound(ar) then msgbox "Your array is empty!"

Dies ist möglicherweise schneller als join (). (Und ich habe nicht mit negativen Indizes überprüft)

Hier ist mein Beispiel zum Filtern von 2 String-Arrays, damit diese nicht dieselben Strings verwenden.

" Filtering ar2 out of strings that exists in ar1

For i = 0 To UBound(ar1)

" filter out any ar2.string that exists in ar1
ar2 = Filter(ar2 , ar1(i), False)

If UBound(ar2) < LBound(ar2) Then
MsgBox "All strings are the same.", vbExclamation, "Operation ignored":
Exit Sub

End If

Next

" At this point, we know that ar2 is not empty and it is filtered
"

-1 für die Antwort № 23
Public Function arrayIsEmpty(arrayToCheck() As Variant) As Boolean
On Error GoTo Err:
Dim forCheck
forCheck = arrayToCheck(0)
arrayIsEmpty = False
Exit Function
Err:
arrayIsEmpty = True
End Function