填充VBAdynamic数组
下面的代码给我错误9“下标超出范围”。 我的意思是声明一个dynamic数组,以便维度随着元素的添加而改变。 在我像JS一样存储内容之前,是否必须在数组上创build一个“点”?
Sub test_array() Dim test() As Integer Dim i As Integer For i = 0 To 3 test(i) = 3 + i Next i End Sub 在for循环中使用像这样的数组上的Redim:
 For i = 0 to 3 ReDim Preserve test(i) test(i) = 3 + i Next i 
 是的,您正在查找ReDim语句,该语句dynamic分配数组中所需的空间量。 
以下声明
 Dim MyArray() 
声明一个没有维度的数组,所以编译器不知道它有多大,不能在里面存储任何东西。
 但是您可以使用ReDim语句来调整数组大小: 
 ReDim MyArray(0 To 3) 
 如果您需要在保留其内容的同时调整数组的大小,则可以使用Preserve关键字和ReDim语句: 
 ReDim Preserve MyArray(0 To 3) 
 但请注意, ReDim和ReDim Preserve都有很高的性能成本。 尽量避免一遍又一遍地在一个循环中进行,如果可能的话; 你的用户会感谢你。 
 但是,在你的问题中显示的简单例子(如果它不只是一次性样品),你根本不需要ReDim 。 只需声明具有明确维度的数组: 
 Dim MyArray(0 To 3) 
 第一次海报,长时间的读者。 正如科迪和布雷特所说的,你可以通过合理使用Redim Preserve来减lessVBA的减速。 布雷特build议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 
 这只有在尺寸增加一倍时才会调用ReDim Preserve 。 成员variableseSize跟踪eSize的实际数据大小。 直到运行时才知道最终的数组长度,这种方法帮助我提高了性能。 
希望这也能帮助别人。
除了科迪的有用的评论,值得注意的是,有时你不会知道你的arrays应该有多大。 在这种情况下的两种select是
- 创build一个足够大的数组来处理任何你认为会被抛出的数组
-   明智地使用Redim Preserve
 下面的代码提供了一个例程,它将根据lngSizevariables对myArray进行维度lngSize ,然后每当上限即将超过时,使用Modtesting添加其他元素(等于初始数组大小) 
 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 
 我看到很多(所有)上面依靠LBound / UBound调用的post,但尚未初始化VBAdynamic数组,什么原因导致应用程序不可避免的死亡… 
不稳定的代码:
 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(...) ,崩溃之后。 回旋是采用On Error Resume Next并在LBound(arr1) / UBound(arr1)调用后检查Err.Number – 如果数组初始化,它应该为0,否则为非零。 由于存在一些VBA内置的不当行为,需要进一步检查数组的限制。 每个人都可以在Chip Pearson的网站上看到详细的解释(应该被称为VBA智慧的人类宝藏 …) 
嘿,这是我的第一篇文章,相信它是清晰的。