以下代码给出了错误9"下标超出范围".我的意思是声明一个动态数组,以便在我向其添加元素时更改维度.在我像JS一样存储内容之前,我是否必须在数组上创建一个"点"?
Sub test_array()
Dim test() As Integer
Dim i As Integer
For i = 0 To 3
test(i) = 3 + i
Next i
End Sub
Run Code Online (Sandbox Code Playgroud)
Flu*_*974 59
在你的for循环中使用数组上的Redim,如下所示:
For i = 0 to 3
ReDim Preserve test(i)
test(i) = 3 + i
Next i
Run Code Online (Sandbox Code Playgroud)
Cod*_*ray 24
是的,您正在寻找ReDim
语句,该语句动态分配数组中所需的空间量.
以下声明
Dim MyArray()
Run Code Online (Sandbox Code Playgroud)
声明一个没有维度的数组,因此编译器不知道它有多大并且不能在其中存储任何内容.
但是您可以使用该ReDim
语句来调整数组的大小:
ReDim MyArray(0 To 3)
Run Code Online (Sandbox Code Playgroud)
如果您需要在保留其内容的同时调整数组大小,可以将该Preserve
关键字与ReDim
语句一起使用:
ReDim Preserve MyArray(0 To 3)
Run Code Online (Sandbox Code Playgroud)
但要注意两者ReDim
并且特别ReDim Preserve
是性能成本很高.尽量避免在循环中反复这样做; 你的用户会感谢你.
但是,在您的问题中显示的简单示例中(如果它不仅仅是一次性样本),您根本不需要ReDim
.只需声明具有显式尺寸的数组:
Dim MyArray(0 To 3)
Run Code Online (Sandbox Code Playgroud)
a50*_*999 24
正如科迪和布雷特所提到的那样,你可以通过合理使用来减少VBA的减速Redim Preserve
.布雷特建议Mod
这样做.
您还可以使用定义的用户Type
并Sub
执行此操作.考虑下面的代码:
Public Type dsIntArrayType
eElems() As Integer
eSize As Integer
End Type
Public Sub PushBackIntArray( _
ByRef dsIntArray As dsIntArrayType, _
ByVal intValue As Integer)
With dsIntArray
If UBound(.eElems) < (.eSize + 1) Then
ReDim Preserve .eElems(.eSize * 2 + 1)
End If
.eSize = .eSize + 1
.eElems(.eSize) = intValue
End With
End Sub
Run Code Online (Sandbox Code Playgroud)
ReDim Preserve
仅在大小加倍时调用此方法.成员变量eSize
跟踪实际数据大小eElems
.这种方法帮助我提高性能,直到运行时才知道最终的数组长度.
希望这也有助于其他人.
bre*_*tdj 11
除了Cody的有用评论之外,值得注意的是,有时您不会知道阵列应该有多大.这种情况下的两个选择是
Redim Preserve
下面的代码提供了一个例程,它将myArray
根据lngSize
变量进行尺寸标注,然后Mod
在即将超过上限时通过使用测试添加其他元素(等于初始数组大小)
Option Base 1
Sub ArraySample()
Dim myArray() As String
Dim lngCnt As Long
Dim lngSize As Long
lngSize = 10
ReDim myArray(1 To lngSize)
For lngCnt = 1 To lngSize*5
If lngCnt Mod lngSize = 0 Then ReDim Preserve myArray(1 To UBound(myArray) + lngSize)
myArray(lngCnt) = "I am record number " & lngCnt
Next
End Sub
Run Code Online (Sandbox Code Playgroud)
Pet*_*nka 10
我看到上面有很多(所有)帖子依赖LBound
/ UBound
调用可能未初始化的VBA动态数组,导致应用程序无法死亡的原因......
不稳定的代码:
Dim x As Long
Dim arr1() As SomeType
...
x = UBound(arr1) 'crashes
正确的代码:
Dim x As Long
Dim arr1() As SomeType
...
ReDim Preserve arr1(0 To 0)
...
x = UBound(arr1)
...即没有在/ 之间Dim arr1()
立即跟随LBound(arr1)
/ UBound(arr1)
呼叫的任何代码ReDim arr1(...)
,崩溃.环形交叉口是在/ call 之后使用On Error Resume Next
并检查Err.Number
右边- 如果数组初始化则应为0,否则为非零.由于存在一些VBA内置的不当行为,因此需要进一步检查数组的限制.每个人都可以在Chip Pearson的网站上阅读详细解释(应该将其视为VBA智慧的人类宝藏 ...)LBound(arr1)
UBound(arr1)
嘿,这是我的第一篇文章,相信它是清晰易读的.