[英]Array “subscript out of range” odd behavior
Consider this code in MS Word VBA: 在MS Word VBA中考虑以下代码:
Sub Test()
Dim x() As Document
ReDim Preserve x(UBound(x) + 1)
Set x(UBound(x)) = Application.ActiveDocument
End Sub
If I place the cursor inside and hit F5 to run it, I get an error 如果我将光标放在里面并按F5键运行它,则会收到错误消息
subscript out of range
下标超出范围
on ReDim Preserve x(UBound(x) + 1)
. 在
ReDim Preserve x(UBound(x) + 1)
。 Specifically, it doesn't like UBound(x)
, although it should return -1
based on MSDN (see under "return value"). 具体来说,它不喜欢
UBound(x)
,尽管它应该基于MSDN返回-1
(请参见“返回值”下的内容)。
Now, if I set a break point on ReDim Preserve x(UBound(x) + 1)
, run it, and then hover the cursor over UBound(x)
, it indicates the same thing: 现在,如果我在
ReDim Preserve x(UBound(x) + 1)
上设置一个断点,运行它,然后将光标悬停在UBound(x)
,则表明相同:
But I've discovered that if I then hover over the variable x
in the following line: 但是我发现,如果我将鼠标悬停在以下行中的变量
x
上:
and then go back and again hover over UBound(x)
in the line above, I get a different result: 然后返回并再次将鼠标悬停在上一行的
UBound(x)
上,我得到一个不同的结果:
Then, if I hit F5 to run the rest of the code, indeed, I get no error that time. 然后,如果我按F5键运行其余代码,的确,那时候我没有出错。
Furthermore, if I change my code to add IsArray(x)
: 此外,如果我更改代码以添加
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
It also runs fine. 它也运行良好。 What is going on, and how can I get my code to work at runtime without the
IsArray(x)
hack? 发生了什么,如何在没有
IsArray(x)
hack的情况下使代码在运行时工作?
MSDN: MSDN:
If Array has only one element, UBound returns 0. If Array has no elements, for example if it is a zero-length string, UBound returns -1.
如果Array只有一个元素,则UBound返回0。如果Array没有元素,例如,如果它是长度为零的字符串,则UBound返回-1。
It isn't that the array has no elements, it is un-initialized, or doesn't have dimensions. 这并不是说数组没有元素,未初始化或没有维度。 You shouldn't rely on the value of
UBound
without first using ReDim
on the array at least once, or without the use of error handling. 在不首先在数组上至少使用一次
ReDim
或不使用错误处理的情况下,您不应该依赖UBound
的值。
A better approach is to use error handling: 更好的方法是使用错误处理:
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
See this link for other considerations. 其他注意事项,请参见此链接 。
Alternatively, if possible, ensure that the array is dimensioned ( ReDim
) as least once. 或者,如果可能,请确保数组的尺寸至少为一次(
ReDim
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.