我想检查空数组。 Google给了我各种解决方案,但没有任何效果也许我没有正确应用它们。
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
如果FileNamesList
数组为空,则根本不应调用GetBoiler(SigString)
。当FileNamesList
数组为空时,SigString
也为空,这将调用带有空字符串的GetBoiler()
函数。我在第
Set ts = fso.GetFile(sFile).OpenAsTextStream(1, -2)
因为sFile
为空。有什么办法可以避免吗?
答案 0 :(得分:73)
在处理字符串数组时,您考虑过加入吗?
If Len(Join(FileNamesList)) > 0 Then
答案 1 :(得分:61)
使用三重否定:
If (Not Not FileNamesList) <> 0 Then
' Array has been initialized, so you're good to go.
Else
' Array has NOT been initialized
End If
或者只是:
If (Not FileNamesList) = -1 Then
' Array has NOT been initialized
Else
' Array has been initialized, so you're good to go.
End If
在VB中,无论出于何种原因,Not myArray
都会返回SafeArray指针。对于未初始化的数组,返回-1。您可以Not
将其与-1进行异或,如果您愿意,则返回零。
(Not myArray) (Not Not myArray)
Uninitialized -1 0
Initialized -someBigNumber someOtherBigNumber
答案 2 :(得分:28)
如果你测试一个数组函数,它将适用于所有边界:
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
答案 3 :(得分:6)
我在这里看到类似的答案......但不是我的......
这就是我不幸要处理它的方式......我喜欢len(join(arr))&gt; 0方法,但如果数组是一个emptystrings数组,它将无法工作......
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
答案 4 :(得分:5)
在写VBA时,我脑子里有这句话:“可能这么容易,但是......”
以下是我采用它的原因:
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
答案 5 :(得分:4)
此代码无法满足您的期望:
If Dir(SigString) <> "" Then
Signature = GetBoiler(SigString)
Else
Signature = ""
End If
如果将空字符串(""
)或vbNullString
传递给Dir
,它将返回当前目录路径中第一个文件的名称({{返回的路径) 1}})。因此,如果CurDir$
为空,则SigString
条件将评估为If
,因为True
将返回非空字符串(当前目录中第一个文件的名称) ),Dir
将被调用。如果GetBoiler
为空,则对SigString
的调用将失败。
您应该更改条件以检查fso.GetFile
是否为空,或使用SigString
方法而不是FileSystemObject.FileExists
来检查文件是否存在。 Dir
使用起来很棘手,因为它可以做你可能不希望它做的事情。就个人而言,我会使用Dir
而不是Scripting.FileSystemObject
,因为没有有趣的商家(如果文件存在,Dir
会返回FileExists
,如果不存在,True
“T)。更重要的是,False
比FileExists
更清楚地表达了代码的 intent 。
方法1:检查Dir
是否为非空首
SigString
方法2:使用If SigString <> "" And Dir(SigString) <> "" Then
Signature = GetBoiler(SigString)
Else
Signature = ""
End If
方法
FileSystemObject.FileExists
答案 6 :(得分:4)
我只是简单地粘贴在伟大的Chip Pearson的代码之下。它很有魅力 这是他的page on array functions。
我希望这会有所帮助。
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
答案 7 :(得分:2)
Auth最接近,但他的回答引发了类型不匹配错误。
至于其他答案,你应该避免使用错误来测试一个条件,如果可以的话,因为它至少会使调试复杂化(如果其他东西导致了那个错误会怎样)。
这是一个简单,完整的解决方案:
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
答案 8 :(得分:2)
基于ahuth&#39; answer;
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
检查空数组; is_empty = AryLen(some_array)=0
答案 9 :(得分:2)
简化检查空数组:
Dim exampleArray() As Variant 'Any Type
If ((Not Not exampleArray) = 0) Then
'Array is Empty
Else
'Array is Not Empty
End If
答案 10 :(得分:1)
Public Function IsEmptyArray(InputArray As Variant) As Boolean
On Error GoTo ErrHandler:
IsEmptyArray = Not (UBound(InputArray) >= 0)
Exit Function
ErrHandler:
IsEmptyArray = True
End Function
答案 11 :(得分:1)
另一种方法是尽快完成。将数据加载到数组后,可以创建一个布尔变量并将其设置为true。所以你真正需要的是一个简单的if语句,说明何时将数据加载到数组中。
答案 12 :(得分:1)
这是另一种方法。我在某些情况下使用它并且它正在工作。
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
答案 13 :(得分:1)
Function IsVarArrayEmpty(anArray As Variant) as boolean
On Error Resume Next
IsVarArrayEmpty = true
IsVarArrayEmpty = UBound(anArray) < LBound(anArray)
End Function
也许ubound
崩溃并且仍然是真的,如果ubound < lbound
,它就是空的
答案 14 :(得分:1)
要检查Byte数组是否为空,最简单的方法是使用VBA函数StrPtr()
。
如果Byte数组为空,StrPtr()
返回0
;否则,它返回一个非零值(但是,不是第一个元素的地址)。
Dim ar() As Byte
Debug.Assert StrPtr(ar) = 0
ReDim ar(0 to 3) As Byte
Debug.Assert StrPtr(ar) <> 0
但是,它只适用于字节数组。
答案 15 :(得分:0)
就个人而言,我认为可以修改上述答案之一以检查数组是否包含内容:
if UBound(ar) > LBound(ar) Then
这会处理负数引用,并且比其他一些选项花费的时间更少。
答案 16 :(得分:0)
您可以使用以下函数检查变量或字符串数组在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
样本用法
Public Function test()
Dim Arr(1) As String
Arr(0) = "d"
Dim x As Boolean
x = IsArrayAllocated(Arr)
End Function
答案 17 :(得分:0)
您可以使用JScript的VBArray()
对象检索总元素数来检查数组是否为空(使用变体类型的数组,单维或多维):
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
对我而言,每个元素大约需要0.3 mksec + 15毫秒初始化,因此10M元素阵列大约需要3秒。可以通过ScriptControl
ActiveX实现相同的功能(它在64位MS Office版本中不可用,因此您可以使用this之类的解决方法。
答案 18 :(得分:0)
if Ubound(yourArray)>-1 then
debug.print "The array is not empty"
else
debug.print "EMPTY"
end if
答案 19 :(得分:0)
我会按预期概括问题和问题。 测试数组上的assing,并捕获最终的错误
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
当然它错过了所有负面索引的数组或全部&gt; 1 ......可能吗?在古怪的地方,是的。
答案 20 :(得分:0)
您可以检查其计数。
此处 cid 是一个数组。
if (jsonObject("result")("cid").Count) = 0 them
MsgBox "Empty Array"
我希望这会有所帮助。 祝你有美好的一天!
答案 21 :(得分:-1)
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
答案 22 :(得分:-1)
测试空数组的另一种解决方案
if UBound(ar) < LBound(ar) then msgbox "Your array is empty!"
或者,如果你已经知道LBound是0
if -1 = UBound(ar) then msgbox "Your array is empty!"
这可能比join()更快。 (我没有用负面指数检查)
以下是我过滤2个字符串数组的示例,因此它们不共享相同的字符串。
' 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
'