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
tableau est vide, GetBoiler(SigString)
ne devrait pas être appelé du tout. Lorsque FileNamesList
tableau est vide, SigString
est également vide et appelle la fonction GetBoiler()
avec une chaîne vide. Je reçois une erreur à la ligne
Set ts = fso.GetFile(sFile).OpenAsTextStream(1, -2)
puisque sFile
est vide. Un moyen d'éviter cela?
Comme vous avez affaire à un tableau de chaînes, avez-vous envisagé de rejoindre?
If Len(Join(FileNamesList)) > 0 Then
Aller 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
this à XOR le avec -1, renvoyant ainsi zéro, si vous préférez.
(Not myArray) (Not Not myArray)
Uninitialized -1 0
Initialized -someBigNumber someOtherBigNumber
Si vous testez 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
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 chaînes vide ...
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
Lors de l'écriture de VBA, il y a cette phrase dans ma tête: "Cela pourrait être si facile, mais ..."
Voici ce que je l'ai adopté pour:
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
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 du chemin du répertoire actuel (le chemin renvoyé par CurDir$
). Donc, si SigString
est vide, votre condition If
sera évaluée à True
car Dir
retournera une chaîne non vide (le nom du premier fichier dans le répertoire en cours), et GetBoiler
sera appelé. Et si SigString
est vide, l’appel à fso.GetFile
va échouer.
Vous devriez soit changer votre condition pour vérifier que SigString
n'est pas vide, soit utiliser le FileSystemObject.FileExists
méthode au lieu de Dir
pour vérifier si le fichier existe. Dir
est difficile à utiliser avec précision, car il fait des choses que vous ne pensiez pas forcément faire. Personnellement, j'utiliserais Scripting.FileSystemObject
over Dir
car il n’ya pas d’affaires amusantes (FileExists
renvoie True
si le fichier existe et, bien, False
s’il n’existe pas). De plus, FileExists
exprime clairement l'intention de votre code bien que Dir
.
Méthode 1: Vérifiez que SigString
est d'abord non vide
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
Je suis simplement en train de coller ci-dessous le code du grand Chip Pearson. Cela fonctionne un charme.
Voici son page sur les fonctions du tablea .
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
Auth était le plus proche, mais sa réponse soulève une erreur d’écart type.
En ce qui concerne les 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 (que se passe-t-il si quelque chose d'autre provoque 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
Vérification simplifiée pour tableau vide:
Dim exampleArray() As Variant 'Any Type
If ((Not Not exampleArray) = 0) Then
'Array is Empty
Else
'Array is Not Empty
End If
Basé sur ahuth's réponse ;
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
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()
renvoie 0
; sinon, il renvoie une valeur non nulle (cependant, il est ne pas l'adresse au 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 Byte.
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é des données dans le tableau. vous n'avez donc besoin que d'une simple instruction if indiquant le moment où vous chargez des données dans le tableau.
Public Function IsEmptyArray(InputArray As Variant) As Boolean
On Error GoTo ErrHandler:
IsEmptyArray = Not (UBound(InputArray) >= 0)
Exit Function
ErrHandler:
IsEmptyArray = True
End Function
Voici une autre façon de le faire. 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
Function IsVarArrayEmpty(anArray As Variant) as boolean
On Error Resume Next
IsVarArrayEmpty = true
IsVarArrayEmpty = UBound(anArray) < LBound(anArray)
End Function
Peut-être que ubound
se bloque et reste à vrai, et si ubound < lbound
, c'est vide
Vous pouvez vérifier son compte.
Ici cid est un tableau.
if (jsonObject("result")("cid").Count) = 0 them
MsgBox "Empty Array"
J'espère que ça aide. Bonne journée!
Vous pouvez vérifier si le tableau est vide en récupérant le nombre total d'éléments à l'aide de l'objet VBArray()
de JScript (fonctionne avec les tableaux de type variant, simples ou multidimensionnels):
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, il faut environ 0,3 mksec pour chaque élément + 15 ms d’initialisation, donc le tableau de 10 M d’éléments prend environ 3 secondes. La même fonctionnalité pourrait être implémentée via ScriptControl
ActiveX (elle n'est pas disponible dans les versions MS Office 64 bits, vous pouvez donc utiliser une solution de contournement comme this ).
if Ubound(yourArray)>-1 then
debug.print "The array is not empty"
else
debug.print "EMPTY"
end if
Je vais généraliser le problème et la question comme prévu. Testez l'évaluation sur le tableau et détectez 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 index négatifs ou tous les> 1 ... est-ce probable? au pays étrange, oui.
Personnellement, je pense qu'une des réponses ci-dessus peut être modifiée pour vérifier si le tableau a un 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.
Vous pouvez utiliser la fonction ci-dessous pour vérifier si le variant ou le tableau de 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