数组“下标超出范围”的奇怪行为

时间:2014-06-10 16:40:41

标签: arrays vba

在MS Word VBA中考虑此代码:

Sub Test()
    Dim x() As Document
    ReDim Preserve x(UBound(x) + 1)
    Set x(UBound(x)) = Application.ActiveDocument
End Sub

如果我将光标放在里面并点击F5来运行它,我会收到错误

  

下标超出范围

<{1>} ReDim Preserve x(UBound(x) + 1)。具体来说,它不喜欢UBound(x),尽管 应基于MSDN返回-1(请参阅“返回值”下方)。

现在,如果我在ReDim Preserve x(UBound(x) + 1)上设置了一个断点,请运行它,然后将光标悬停在UBound(x)上,它表示同样的事情:

enter image description here

但是我发现如果我将鼠标悬停在以下行中的变量x上:

enter image description here

然后返回并再次悬停在上面一行的UBound(x)上,我得到了不同的结果:

enter image description here

然后,如果我按F5运行剩下的代码,确实,那段时间没有错误。

此外,如果我更改我的代码以添加IsArray(x)

Sub Test()
    Dim x() As Document
    IsArray (x) 'This is just here to preclude VBA array "bug"
    ReDim Preserve x(UBound(x) + 1)
    Set x(UBound(x)) = Application.ActiveDocument
End Sub

它也运行良好。发生了什么,如何在没有IsArray(x) hack的情况下让我的代码在运行时工作?

1 个答案:

答案 0 :(得分:0)

MSDN:

  

如果Array只有一个元素,则UBound返回0.如果Array没有   元素,例如,如果它是一个零长度的字符串,UBound返回   -1

数组没有元素,没有初始化,或者没有维度。如果没有首先在阵列上使用UBound,或者不使用错误处理,则不应该依赖ReDim的值。

更好的方法是使用错误处理:

Dim x() As Document

Dim n As Long
On Error Resume Next
Err.Clear
n = LBound(x)
If Err.Number = 0 Then
    Debug.Print "Array is allocated."
Else
    Debug.Print "Array is not allocated."
End If

有关其他注意事项,请参阅此link

或者,如果可能,请确保数组的大小(ReDim)至少为一次。