检查数组是否为空(vba excel)

时间:2014-10-10 01:58:04

标签: excel-vba vba excel

这些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

7 个答案:

答案 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
相关问题