/ / Jak sprawdzić pustą tablicę w makrze vba - excel, vba, excel-vba

Jak sprawdzić pustą tablicę w makrze vba - excel, vba, excel-vba

Chcę sprawdzić puste tablice. Google dał mi różne rozwiązania, ale nic nie działało. Może nie stosuję ich poprawnie.

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

Tutaj jeśli FileNamesList tablica jest pusta, GetBoiler(SigString) nie powinno się w ogóle dzwonić. Gdy FileNamesList tablica jest pusta, SigString jest również pusty i to wywołanie GetBoiler() funkcja z pustym łańcuchem. Mam błąd na linii

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

od sFile jest pusty. Jakikolwiek sposób, aby tego uniknąć?

Odpowiedzi:

66 dla odpowiedzi nr 1

Czy mając do czynienia z tablicą ciągów, rozważałeś dołączenie?

If Len(Join(FileNamesList)) > 0 Then

44 dla odpowiedzi nr 2

Idź z potrójnym negatywem:

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

Lub tylko:

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

W VB z jakiegokolwiek powodu Not myArray zwraca wskaźnik SafeArray. W przypadku niezainicjowanych tablic zwraca to -1. Możesz Not to, aby XOR go z -1, a więc powróci zero, jeśli wolisz.

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

Źródło


26 dla odpowiedzi nr 3

Jeśli testujesz na funkcji tablicowej, będzie działał dla wszystkich granic:

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 dla odpowiedzi № 4

Widzę podobne odpowiedzi tutaj ... ale nie moje ...

W ten sposób jestem niefortunny, że sobie z tym poradzę ... Podoba mi się podejście len (join (arr))> 0, ale nie zadziałałoby, gdyby tablica była tablicą pustych łańcuchów ...

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 dla odpowiedzi № 5

Pisząc VBA, mam w głowie zdanie: „Może być takie proste, ale…”

Oto, co przyjąłem do:

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 dla odpowiedzi № 6

Ten kod nie robi tego, czego oczekujesz:

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

Jeśli podasz pusty ciąg ("") lub vbNullString do Dir, zwróci nazwę pierwszego pliku w bieżącej ścieżce katalogu (ścieżka zwrócona przez CurDir$). Więc jeśli SigString jest pusty, twój If warunek zostanie oceniony True bo Dir zwróci niepusty łańcuch (nazwa pierwszego pliku w bieżącym katalogu) i GetBoiler będzie wezwany. I jeśli SigString jest pusty, wezwanie do fso.GetFile zawiedzie.

Powinieneś albo zmienić swój stan, aby to sprawdzić SigString nie jest pusty lub użyj FileSystemObject.FileExists metoda zamiast Dir do sprawdzenia, czy plik istnieje. Dir jest trudny w użyciu właśnie dlatego, że robi rzeczy, których możesz się nie spodziewać. Osobiście użyłbym Scripting.FileSystemObject koniec Dir bo nie ma zabawnego biznesu (FileExists zwraca True jeśli plik istnieje, i, cóż, False jeśli tak nie jest, to co więcej, FileExists wyraża zamiar twojego kodu znacznie bardziej niż Dir.

Metoda 1: Sprawdź to SigString jest niepusty

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

Metoda 2: Użyj FileSystemObject.FileExists metoda

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

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

4 dla odpowiedzi № 7

Po prostu wklejam poniżej kodu wielkiego Chipa Pearsona. To działa urok.
Oto jego strona na funkcjach tablicy.

Mam nadzieję, że to pomoże.

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 dla odpowiedzi № 8

Auth był najbliższy, ale jego odpowiedź powoduje błąd niezgodności typu.

Jeśli chodzi o inne odpowiedzi, powinieneś unikać błędów, aby przetestować warunek, jeśli możesz, ponieważ co najmniej komplikuje debugowanie (co jeśli coś innego powoduje ten błąd).

Oto proste, kompletne rozwiązanie:

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 dla odpowiedzi № 9

Uproszczone sprawdzenie pustej tablicy:

Dim exampleArray() As Variant "Any Type

If ((Not Not exampleArray) = 0) Then
"Array is Empty
Else
"Array is Not Empty
End If

2 dla odpowiedzi № 10

Na podstawie ahuth ”s odpowiedź;

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

Sprawdź pustą tablicę; is_empty = AryLen(some_array)=0


1 dla odpowiedzi № 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 dla odpowiedzi № 12

Inną metodą byłoby zrobić to wcześniej. Możesz utworzyć zmienną boolowską i ustawić ją na true po załadowaniu danych do tablicy. więc wszystko, czego naprawdę potrzebujesz, to prosta instrukcja if podczas ładowania danych do tablicy.


1 dla odpowiedzi № 13

Oto inny sposób, aby to zrobić. Używałem go w niektórych przypadkach i to działa.

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 dla odpowiedzi № 14

Aby sprawdzić, czy tablica bajtów jest pusta, najprostszym sposobem jest użycie funkcji VBA StrPtr().

Jeśli tablica bajtów jest pusta, StrPtr() zwraca 0; w przeciwnym razie zwraca wartość niezerową (jednak jest nie adres do pierwszego elementu).

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

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

Jednak działa tylko z tablicą Byte.


0 dla odpowiedzi № 15

Uogólnię problem i pytanie zgodnie z przeznaczeniem. Sprawdź przyporządkowanie na tablicy i złap ewentualny błąd

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

Pewnie, że brakuje tablic ze wszystkimi ujemnymi indeksami lub wszystkie> 1 ... czy to prawdopodobne? w dziwnym miejscu, tak.


0 dla odpowiedzi № 16

Osobiście uważam, że jedną z powyższych odpowiedzi można zmodyfikować, aby sprawdzić, czy tablica ma zawartość:

if UBound(ar) > LBound(ar) Then

To obsługuje negatywne numery referencyjne i zajmuje mniej czasu niż inne opcje.


0 dla odpowiedzi № 17

Możesz użyć poniższej funkcji, aby sprawdzić, czy wariant lub tablica ciągów jest pusta w vba

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

Wykorzystanie próbki

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

0 dla odpowiedzi № 18

Możesz sprawdzić, czy tablica jest pusta, pobierając całkowitą liczbę elementów za pomocą JScript VBArray() obiekt (działa z tablicami typu wariantowego, pojedynczego lub wielowymiarowego):

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

Dla mnie zajmuje to około 0,3 milisekundy na każdy element + 15 milisekund inicjalizacji, więc macierz elementów 10M zajmuje około 3 sekund. Ta sama funkcjonalność mogłaby zostać zaimplementowana za pośrednictwem ScriptControl ActiveX (nie jest dostępny w 64-bitowych wersjach MS Office, więc możesz użyć obejścia takiego jak to).


0 dla odpowiedzi № 19
if Ubound(yourArray)>-1 then
debug.print "The array is not empty"
else
debug.print "EMPTY"
end if

0 dla odpowiedzi № 20
Function IsVarArrayEmpty(anArray As Variant) as boolean
On Error Resume Next
IsVarArrayEmpty = true
IsVarArrayEmpty = UBound(anArray) < LBound(anArray)
End Function

Może ubound zawiesza się i pozostaje prawdą, a jeśli ubound < lbound, to jest puste


0 dla odpowiedzi № 21

Możesz sprawdzić jego liczbę.

Tutaj cid jest tablicą.

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

Mam nadzieję, że to pomoże. Miłego dnia!


-1 za odpowiedź nr 22

Kolejne rozwiązanie do testowania pustej tablicy

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

Lub, jeśli już wiesz, że LBound ma wartość 0

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

Może to być szybsze niż dołączanie (). (I nie sprawdzałem z ujemnymi indeksami)

Oto moja próbka filtrowania 2 tablic ciągów, aby nie udostępniały tych samych ciągów.

" 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 za odpowiedź nr 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