/ / Como verificar a matriz vazia na macro vba - excel, vba, excel-vba

Como verificar a matriz vazia na macro vba - excel, vba, excel-vba

Quero verificar se há matrizes vazias. O Google me deu várias soluções, mas nada funcionou. Talvez eu não os esteja aplicando corretamente.

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

Aqui se FileNamesList matriz está vazia, GetBoiler(SigString) não deve ser chamado. Quando FileNamesList matriz está vazia, SigString também está vazio e isso chama GetBoiler() função com string vazia. Eu recebo um erro na linha

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

Desde a sFile está vazia. Alguma maneira de evitar isso?

Respostas:

66 para resposta № 1

Ao lidar com uma matriz de cadeias de caracteres, você considerou Join?

If Len(Join(FileNamesList)) > 0 Then

44 para resposta № 2

Vá com um triplo negativo:

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

Ou apenas:

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

No VB, por qualquer motivo, Not myArray retorna o ponteiro SafeArray. Para matrizes não inicializadas, isso retorna -1. Você pode Not para XOR com -1, retornando zero, se você preferir.

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

Fonte


26 for answer № 3

Se você testar uma função de matriz, ela funcionará para todos os limites:

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 para resposta № 4

Vejo respostas semelhantes aqui ... mas não as minhas ...

É assim que, infelizmente, vou lidar com isso ... Gosto da abordagem len (join (arr))> 0, mas não funcionaria se a matriz fosse uma matriz de strings vazias ...

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 para a resposta № 5

Ao escrever o VBA, há uma frase na minha cabeça: "Pode ser tão fácil, mas ..."

Aqui está o que eu adotei:

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 para resposta № 6

Este código não faz o que você espera:

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

Se você passar uma string vazia ("") ou vbNullString para Dir, ele retornará o nome do primeiro arquivo no caminho do diretório atual (o caminho retornado por CurDir$) Então se SigString está vazio, seu If condição avaliará True Porque Dir retornará uma string não vazia (o nome do primeiro arquivo no diretório atual) e GetBoiler será chamado. E se SigString está vazio, a chamada para fso.GetFile vai falhar.

Você deve alterar sua condição para verificar se SigString não estiver vazio ou use o FileSystemObject.FileExists método em vez de Dir para verificar se o arquivo existe. Dir é difícil de usar exatamente porque faz coisas que você não espera que faça. Pessoalmente, eu usaria Scripting.FileSystemObject sobre Dir porque não há nenhum negócio engraçado (FileExists retorna True se o arquivo existir e, bem, False se isso não acontecer. O que é mais, FileExists expressa o intenção do seu código muito claramente do que Dir.

Método 1: verifique se SigString é não vazio primeiro

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

Método 2: Use o FileSystemObject.FileExists método

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

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

4 para resposta № 7

Estou simplesmente colando abaixo do código pelo grande Chip Pearson. Isso funciona um encanto.
Aqui está o dele página em funções de matriz.

Eu espero que isso ajude.

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 para resposta № 8

O Auth foi o mais próximo, mas sua resposta gera um erro de incompatibilidade de tipo.

Quanto às outras respostas, você deve evitar usar um erro para testar uma condição, se puder, porque pelo menos isso complica a depuração (e se outra coisa estiver causando esse erro).

Aqui está uma solução simples e completa:

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 para resposta № 9

Verificação simplificada para a matriz vazia:

Dim exampleArray() As Variant "Any Type

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

2 para resposta № 10

Baseado em ahuth "s responda;

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

Verifique se há uma matriz vazia; is_empty = AryLen(some_array)=0


1 para resposta № 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 para resposta № 12

Outro método seria fazê-lo mais cedo. Você pode criar uma variável booleana e configurá-la como true quando carregar os dados na matriz. então tudo que você realmente precisa é de uma declaração if simples de quando você carrega dados na matriz.


1 para a resposta № 13

Aqui está outra maneira de fazer isso. Eu usei em alguns casos e está funcionando.

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 para a resposta № 14

Para verificar se uma matriz de bytes está vazia, a maneira mais simples é usar a função VBA StrPtr().

Se a matriz de bytes estiver vazia, StrPtr() retorna 0; caso contrário, ele retornará um valor diferente de zero (no entanto, é " não o endereço do primeiro elemento).

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

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

No entanto, ele funciona apenas com a matriz de bytes.


0 para a resposta № 15

Generalizarei o problema e a pergunta como pretendido. Teste a classificação na matriz e identifique o eventual erro

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

Claro que falta arrays com todos os índices negativos ou todos> 1 ... isso é provável? na terra estranha, sim.


0 para a resposta № 16

Pessoalmente, acho que uma das respostas acima pode ser modificada para verificar se a matriz possui conteúdo:

if UBound(ar) > LBound(ar) Then

Isso lida com referências numéricas negativas e leva menos tempo que algumas das outras opções.


0 para a resposta № 17

Você pode usar a função abaixo para verificar se a variante ou matriz de strings está vazia no 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

Uso da amostra

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

0 para a resposta № 18

Você pode verificar se a matriz está vazia, recuperando a contagem total de elementos usando JScript "s VBArray() objeto (trabalha com matrizes do tipo variante, única ou multidimensional):

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

Para mim, são necessários cerca de 0,3 mksec para cada elemento + 15 mseg de inicialização; portanto, a matriz de 10 milhões de elementos leva cerca de 3 segundos. A mesma funcionalidade pode ser implementada via ScriptControl ActiveX (não está disponível nas versões de 64 bits do MS Office, para que você possa usar soluções alternativas, como esta).


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

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

Talvez ubound falha e permanece verdadeiro, e se ubound < lbound, está vazio


0 para a resposta № 21

Você pode verificar sua contagem.

Aqui cid é uma matriz.

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

Eu espero que isso ajude. Tenha um bom dia!


-1 para a resposta № 22

Outra solução para testar a matriz vazia

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

Ou, se você já sabe que LBound é 0

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

Isso pode ser mais rápido que o join (). (E não verifiquei com índices negativos)

Aqui está minha amostra para filtrar duas matrizes de string para que elas não compartilhem as mesmas strings.

" 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 para resposta № 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