Dim Result() As Variant
在我的观察窗口中,显示为
Expression | Value | Type
Result | | Variant/Variant()
如何查看以下内容:
if Result is nothing then
或
if Result is Not Set then
这基本上是我想要完成的,但第一个不起作用,第二个不存在。
答案 0 :(得分:15)
为了避免错误处理,我使用了这个,很久以前就在论坛上看到过,并且从那时起成功使用:
If (Not Not Result) <> 0 Then 'Means it is allocated
或者
If (Not Not Result) = 0 Then 'Means it is not allocated
我主要用这种方法从unset数组扩展数组大小
'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
答案 1 :(得分:10)
您可以在即时窗口中使用以下内容:
?Result Is Nothing
?IsNull( Result )
?IsEmpty( Result )
?IsMissing( Result )
首先是完整性。由于Result不是对象,Result Is Nothing
将抛出错误。 Empty
适用于尚未初始化的变种,包括尚未标注尺寸的数组。。
(更新)在做一些额外的检查时,我发现只有一个例外,IsEmpty永远不会在声明的数组(无论是否Redim)上返回true。我发现的唯一例外是当数组在模块级别而不是Public时声明,然后只有在立即窗口中检查它时。
Missing
if if for optional values是否传递给函数或sub。虽然您无法声明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çoisCorbett发布的库)将返回false。
答案 2 :(得分:8)
Chip Pearson制作了一个名为modArraySupport的有用模块,它包含一系列功能来测试这样的事情。在您的情况下,您可能希望使用IsArrayAllocated
。
Public Function IsArrayAllocated(Arr As Variant) As Boolean
此函数返回TRUE或FALSE,指示是否已分配指定的数组(非空)。返回的TRUE array是静态数组或已使用Redim语句分配的动态数组。如果数组是动态数组,则返回FALSE 尚未使用ReDim调整大小或已使用Erase语句取消分配。这个功能基本上是相反的 ArrayIsEmpty。例如,
Dim Result() As Variant
Dim R As Boolean
R = IsArrayAllocated(Result) ' returns false
ReDim V(1 To 10)
R = IsArrayAllocated(Result) ' returns true
使用的技术基本上是测试数组边界(由@Tim Williams建议)但是有额外的问题。
要在即时窗口中进行测试:
?IsArrayAllocated(Result)
在Watch窗口中进行测试:有很多方法可以做到这一点;例如,在R
上添加一个监视,在“监视类型”下选择“值改变时休息”。
答案 3 :(得分:0)
检查阵列的LBound
。如果你收到错误,那么它就是未初始化的。
答案 4 :(得分:0)
我建议采用稍微不同的方法,因为我认为使用像(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%的向量存储空间被浪费了。
答案 5 :(得分:0)
我认为已接受答案的第4行应该说:
ReDim Result(1 To 10)
代替:
ReDim V(1 To 10)
我相信第5行:
R = IsArrayAllocated(Result) ' returns true
将像第3行一样返回FALSE。
R = IsArrayAllocated(Result) ' returns false
因为结果不是第4行中重新定义的内容。
在第4行中,尝试重新命名称为V的数组,但甚至没有声明它。