这些if ... then语句在我看来是错误的结果。第一个是返回值' false'什么时候应该是真的'。第四个返回正确的值。第二个和第三个返回错误。
Sub empty_array()
Dim arr1() As Variant
If IsEmpty(arr1) Then
MsgBox "hey"
End If
If IsError(UBound(arr1)) Then
MsgBox "hey"
End If
If IsError(Application.match("*", (arr1), 0)) Then
MsgBox "hey"
End If
ReDim arr1(1)
arr1(1) = "hey"
If IsEmpty(arr1) Then
MsgBox "hey"
End If
End Sub
答案 0 :(得分:10)
Arr1通过代码的第一个语句变成'Variant'数组:
Dim arr1() As Variant
大小为零的数组不为空,就像现实世界中存在一个空盒子一样。
如果您定义了一个'Variant'变量,那么在创建它时它将为空。
以下代码将显示“Empty”。
Dim a as Variant
If IsEmpty(a) then
MsgBox("Empty")
Else
MsgBox("Not Empty")
End If
答案 1 :(得分:3)
我会这样做
if isnumeric(ubound(a)) = False then msgbox "a is empty!"
答案 2 :(得分:2)
添加到此:它取决于您的数组定义为什么。考虑:
dim a() as integer
dim b() as string
dim c() as variant
'these doesn't work
if isempty(a) then msgbox "integer arrays can be empty"
if isempty(b) then msgbox "string arrays can be empty"
'this is because isempty can only be tested on classes which have an .empty property
'this do work
if isempty(c) then msgbox "variants can be empty"
那么,我们能做什么?在VBA中,我们可以看到是否可以触发错误并以某种方式处理它,例如
dim a() as integer
dim bEmpty as boolean
bempty=false
on error resume next
bempty=not isnumeric(ubound(a))
on error goto 0
但这真的很笨拙......一个更好的解决方案是声明一个布尔变量(公共或模块级别最好)。首次初始化数组时,然后设置此变量。 因为它是同时声明的变量,如果它失去了它的值,那么你知道你需要重新初始化你的数组。 但是,如果它已初始化,那么您所做的只是检查布尔值,这是一个低成本。这取决于是否是低成本问题,以及您是否需要经常检查它。
option explicit
'declared at module level
dim a() as integer
dim aInitialised as boolean
sub DoSomethingWithA()
if not aInitialised then InitialiseA
'you can now proceed confident that a() is intialised
end sub
sub InitialiseA()
'insert code to do whatever is required to initialise A
'e.g.
redim a(10)
a(1)=123
'...
aInitialised=true
end sub
你可以做的最后一件事就是创造一个功能;在这种情况下,需要依赖于笨拙的错误方法。
function isInitialised(byref a() as variant) as boolean
isInitialised=false
on error resume next
isinitialised=isnumeric(ubound(a))
end function
答案 3 :(得分:1)
@jeminar是上述最佳解决方案。
我还是整理了一下。
我建议将此添加到FunctionsArray模块中
isInitialised=false
,因为创建时布尔值为假On Error GoTo 0
在类似于with
的错误块内包装和缩进代码以提高可见性。这些方法应尽可能避免,但是... VBA ... Function isInitialised(ByRef a() As Variant) As Boolean
On Error Resume Next
isInitialised = IsNumeric(UBound(a))
On Error GoTo 0
End Function
答案 4 :(得分:0)
以上方法对我不起作用。这样做了:
Dim arrayIsNothing As Boolean
On Error Resume Next
arrayIsNothing = IsNumeric(UBound(ListaProdutosKaptron)) And False
If Err.Number <> 0 Then arrayIsNothing = True
On Error GoTo 0
'Now you can test:
if arrayIsNothing then ...
答案 5 :(得分:0)
VBA的问题是动态数组和静态数组都存在...
动态数组示例
Dim myDynamicArray() as Variant
静态数组示例
Dim myStaticArray(10) as Variant
Dim myOtherStaticArray(0 To 10) as Variant
使用错误处理来检查数组是否为空数组适用于动态数组,但是根据定义,静态数组也不为空,即使所有这些条目都是空的,数组中也有条目。
因此,为了清楚起见,我将函数命名为“ IsZeroLengthArray”。
Public Function IsZeroLengthArray(ByRef subject() As Variant) As Boolean
'Tell VBA to proceed if there is an error to the next line.
On Error Resume Next
Dim UpperBound As Integer
Dim ErrorNumber As Long
Dim ErrorDescription As String
Dim ErrorSource As String
'If the array is empty this will throw an error because a zero-length
'array has no UpperBound (or LowerBound).
'This only works for dynamic arrays. If this was a static array there
'would be both an upper and lower bound.
UpperBound = UBound(subject)
'Store the Error Number and then clear the Error object
'because we want VBA to treat unintended errors normally
ErrorNumber = Err.Number
ErrorDescription = Err.Description
ErrorSource = Err.Source
Err.Clear
On Error GoTo 0
'Check the Error Object to see if we have a "subscript out of range" error.
'If we do (the number is 9) then we can assume that the array is zero-length.
If ErrorNumber = 9 Then
IsZeroLengthArray = True
'If the Error number is something else then 9 we want to raise
'that error again...
ElseIf ErrorNumber <> 0 Then
Err.Raise ErrorNumber, ErrorSource, ErrorDescription
'If the Error number is 0 then we have no error and can assume that the
'array is not of zero-length
ElseIf ErrorNumber = 0 Then
IsZeroLengthArray = False
End If
End Function
我希望这对其他人有所帮助。
答案 6 :(得分:-1)
这对我有用:
Private Function arrIsEmpty(arr as variant)
On Error Resume Next
arrIsEmpty = False
arrIsEmpty = IsNumeric(UBound(arr))
End Function