16
   Dim Result() As Variant

在我的监视窗口中,这显示为

Expression | Value | Type
Result     |       | Variant/Variant()

如何检查以下内容:

   if Result is nothing then

或者

   if Result is Not Set then

这基本上是我想要完成的,但第一个不起作用,第二个不存在。

4

5 回答 5

36

为了避免错误处理,我使用了这个,很久以前在一个论坛上看到并从那时起成功使用:

If (Not Not Result) <> 0 Then 'Means it is allocated

或者

If (Not Not Result) = 0 Then 'Means it is not allocated

我主要用这种方式从未设置的数组中扩展数组大小

'Declare array
Dim arrIndex() As Variant        

'Extend array
If (Not Not Result) = 0 Then
    ReDim Preserve Result(0 To 0)
Else
    ReDim Preserve Result(0 To UBound(Result) + 1)
End If
于 2017-08-25T13:25:59.167 回答
10

您可以在即时窗口中使用以下内容:

?Result Is Nothing
?IsNull( Result )
?IsEmpty( Result )
?IsMissing( Result )

第一个只是为了完整性。由于 Result 不是对象,Result Is Nothing因此会抛出错误。Empty适用于尚未初始化的变体,包括尚未标注尺寸的数组。.

(更新)在做一些额外的检查时,我发现 IsEmpty 永远不会在声明的数组(无论是否 Redim'd)上返回 true,只有一个例外。我发现的唯一例外是当数组在模块级别声明而不是公共时,只有当您在即时窗口中检查它时。

Missingif 对于传递给函数或子的可选值。虽然您不能声明Optional Foo() As Variant,但您可能会遇到类似ParamArray Foo() As Variant的情况,如果没有传递任何内容,IsMissing则会返回 true。

因此,确定数组是否已初始化的唯一方法是编写一个过程来检查:

Public Function IsDimensioned(vValue As Variant) As Boolean
    On Error Resume Next
    If Not IsArray(vValue) Then Exit Function
    Dim i As Integer
    i = UBound(Bar)
    IsDimensioned = Err.Number = 0
End Function

顺便说一句,应该注意的是,如果数组被确定尺寸然后被擦除,这个例程(或 Jean-François Corbett 发布的库)将返回 false。

于 2011-03-30T00:49:40.297 回答
9

Chip Pearson 制作了一个名为modArraySupport的有用模块,其中包含一堆函数来测试此类事情。在你的情况下,你会想要使用IsArrayAllocated.

Public Function IsArrayAllocated(Arr As Variant) As Boolean

此函数返回 TRUE 或 FALSE,指示指定的数组是否已分配(非空)。返回 TRUE 数组是静态数组还是已使用 Redim 语句分配的动态数组。如果数组是尚未使用 ReDim 调整大小或已使用 Erase 语句解除分配的动态数组,则返回 FALSE。这个函数与 ArrayIsEmpty 基本相反。例如,

Dim V() As Variant
Dim R As Boolean
R = IsArrayAllocated(V)  ' returns false
ReDim V(1 To 10)
R = IsArrayAllocated(V)  ' returns true

使用的技术基本上是测试数组边界(如@Tim Williams 所建议的那样),但有一个额外的陷阱。

在您的即时窗口中进行测试:

?IsArrayAllocated(Result)

在 Watch 窗口中进行测试:有一些方法可以做到这一点;例如,在“Watch Type”上添加一个手表,R然后在“Watch Type”下选择“Break When Value Changes”。

于 2011-03-30T07:50:50.323 回答
1

我推荐一种稍微不同的方法,因为我认为使用诸如(Not Array) = -1检查初始化之类的语言工件很难阅读并且会导致维护问题。

如果您需要检查数组分配,很可能是因为您正在尝试创建自己的“向量”类型:一个在运行时增长以适应添加数据的数组。如果您利用类型系统,VBA 使实现向量类型变得相当容易。

Type Vector
    VectorData() As Variant
    VectorCount As Long
End Type

Dim MyData As Vector

Sub AddData(NewData As Variant)
    With MyData
        ' If .VectorData hasn't been allocated yet, allocate it with an
        ' initial size of 16 elements.
        If .VectorCount = 0 Then ReDim .VectorData(1 To 16)

        .VectorCount = .VectorCount + 1

        ' If there is not enough storage for the new element, double the
        ' storage of the vector.
        If .VectorCount > UBound(.VectorData) Then
            ReDim Preserve .VectorData(1 To UBound(.VectorData) * 2)
        End If

        .VectorData(.VectorCount) = NewData
    End With
End Sub

' Example of looping through the vector:
For I = 1 To MyData.VectorCount
    ' Process MyData.VectorData(I)
Next

注意在这段代码中没有必要检查数组分配,因为我们可以只检查VectorCount变量。如果它为 0,我们知道还没有向向量添加任何内容,因此数组未分配。

这段代码不仅简单明了,向量还具有数组的所有性能优势,添加元素的摊销成本实际上是 O(1),非常高效。唯一的权衡是,由于每次向量用完空间时存储会翻倍,在最坏的情况下,向量存储的 50% 被浪费了。

于 2018-04-06T18:56:08.267 回答
-1

检查LBound阵列的。如果你得到一个错误,那么它是未初始化的。

于 2011-03-30T01:24:33.837 回答