/ / Comment vérifier un tableau vide dans une macro vba - excel, vba, excel-vba

Comment vérifier un tableau vide dans une macro vba - Excel, VBA, Excel-VBA

Je veux vérifier les tableaux vides. Google m'a donné des solutions variées mais rien n'a fonctionné. Peut-être que je ne les applique pas correctement.

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

Ici si FileNamesList le tableau est vide, GetBoiler(SigString) ne devrait pas être appelé du tout. Quand FileNamesList le tableau est vide, SigString est également vide et cela appelle GetBoiler() fonction avec chaîne vide. Je reçois une erreur à la ligne

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

depuis sFile est vide. Comment éviter cela?

Réponses:

66 pour la réponse № 1

Comme vous avez affaire à un tableau de chaînes, avez-vous envisagé Join?

If Len(Join(FileNamesList)) > 0 Then

44 pour la réponse № 2

Allez avec un triple négatif:

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 juste:

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

En VB, pour une raison quelconque, Not myArray renvoie le pointeur SafeArray. Pour les tableaux non initialisés, cela renvoie -1. Vous pouvez Not ceci pour le XOR avec -1, retournant ainsi zéro, si vous préférez.

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

La source


26 pour la réponse № 3

Si vous testez sur une fonction de tableau, cela fonctionnera pour toutes les 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 pour la réponse № 4

Je vois des réponses similaires ici ... mais pas les miennes ...

C'est ainsi que je vais malheureusement y faire face ... J'aime l'approche len (join (arr))> 0, mais cela ne fonctionnerait pas si le tableau était un tableau de vidages ...

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 pour la réponse № 5

Lorsque j'écris VBA, il y a cette phrase dans ma tête: "Cela pourrait être si facile, mais ..."

Voici à quoi je l'ai adopté:

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 pour la réponse № 6

Ce code ne fait pas ce que vous attendez:

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

Si vous passez une chaîne vide ("") ou vbNullString à Dir, il renverra le nom du premier fichier dans le chemin du répertoire courant (le chemin retourné par CurDir$). Donc si SigString est vide, votre If condition évaluera à True car Dir renverra une chaîne non vide (le nom du premier fichier dans le répertoire courant), et GetBoiler sera appelé. Et si SigString est vide, l'appel à fso.GetFile va échouer.

Vous devez soit changer votre condition pour vérifier que SigString n'est pas vide, ou utilisez le FileSystemObject.FileExists méthode au lieu de Dir pour vérifier si le fichier existe. Dir est délicat à utiliser précisément parce qu'il fait des choses auxquelles vous ne vous attendez pas. Personnellement, j'utiliserais Scripting.FileSystemObject plus de Dir car il n'y a rien de drôle (FileExists résultats True si le fichier existe, et, eh bien, False si ce n'est pas le cas. De plus, FileExists exprime le intention de votre code beaucoup plus clairement que Dir.

Méthode 1: vérifiez que SigString n'est pas vide en premier

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

Méthode 2: utilisez le FileSystemObject.FileExists méthode

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

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

4 pour la réponse № 7

Je colle simplement sous le code du grand Chip Pearson. Cela fonctionne un charme.
Voici son page sur les fonctions de tableau.

J'espère que ça aide.

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 pour la réponse № 8

Auth était le plus proche, mais sa réponse renvoie une erreur de non-correspondance de type.

Quant aux autres réponses, vous devriez éviter d'utiliser une erreur pour tester une condition, si vous le pouvez, car au moins cela complique le débogage (et si quelque chose d'autre est à l'origine de cette erreur).

Voici une solution simple et complète:

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 pour la réponse № 9

Vérification simplifiée du tableau vide:

Dim exampleArray() As Variant "Any Type

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

2 pour la réponse № 10

Basé sur ahuth "s répondre;

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

Recherchez un tableau vide; is_empty = AryLen(some_array)=0


1 pour la réponse № 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 pour la réponse № 12

Une autre méthode serait de le faire plus tôt. Vous pouvez créer une variable booléenne et la définir sur true une fois que vous avez chargé les données dans le tableau. donc tout ce dont vous avez vraiment besoin est une simple instruction if indiquant quand vous chargez des données dans le tableau.


1 pour la réponse № 13

Voici une autre façon de procéder. Je l'ai utilisé dans certains cas et ça marche.

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 pour la réponse № 14

Pour vérifier si un tableau d'octets est vide, le moyen le plus simple consiste à utiliser la fonction VBA StrPtr().

Si le tableau d'octets est vide, StrPtr() résultats 0; sinon, il renvoie une valeur non nulle (cependant, il "s ne pas l'adresse du premier élément).

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

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

Cependant, cela ne fonctionne qu'avec le tableau d'octets.


0 pour la réponse № 15

Je vais généraliser le problème et la question comme prévu. Tester l'assingment sur la baie et détecter l'erreur éventuelle

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

Bien sûr, il manque des tableaux avec tous les indices négatifs ou tous> 1 ... est-ce probable? dans weirdland, oui.


0 pour la réponse № 16

Personnellement, je pense que l'une des réponses ci-dessus peut être modifiée pour vérifier si le tableau a du contenu:

if UBound(ar) > LBound(ar) Then

Cela gère les références numériques négatives et prend moins de temps que certaines des autres options.


0 pour la réponse № 17

Vous pouvez utiliser la fonction ci-dessous pour vérifier si le tableau des variantes ou des chaînes est vide dans 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

Utilisation de l'échantillon

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

0 pour la réponse № 18

Vous pouvez vérifier si le tableau est vide en récupérant le nombre total d'éléments à l'aide de JScript VBArray() objet (fonctionne avec des tableaux de type variant, unique ou multidimensionnel):

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

Pour moi, cela prend environ 0,3 mksec pour chaque élément + 15 ms d'initialisation, donc le tableau de 10M éléments prend environ 3 secondes. La même fonctionnalité pourrait être implémentée via ScriptControl ActiveX (il n'est pas disponible dans les versions MS Office 64 bits, vous pouvez donc utiliser une solution de contournement comme ce).


0 pour la réponse № 19
if Ubound(yourArray)>-1 then
debug.print "The array is not empty"
else
debug.print "EMPTY"
end if

0 pour la réponse № 20
Function IsVarArrayEmpty(anArray As Variant) as boolean
On Error Resume Next
IsVarArrayEmpty = true
IsVarArrayEmpty = UBound(anArray) < LBound(anArray)
End Function

Peut être ubound plante et il reste vrai, et si ubound < lbound, c'est vide


0 pour la réponse № 21

Vous pouvez vérifier son nombre.

Ici cid est un tableau.

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

J'espère que ça aide. Bonne journée!


-1 pour la réponse № 22

Une autre solution pour tester un tableau vide

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

Ou, si vous savez déjà que LBound vaut 0

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

Cela peut être plus rapide que join (). (Et je n'ai pas vérifié avec des indices négatifs)

Voici mon exemple pour filtrer 2 tableaux de chaînes afin qu'ils ne partagent pas les mêmes chaînes.

" 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 pour la réponse № 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