擦除后下标超出范围

Subscript out of Range after Erase

以下最小示例会崩溃,直到 Erase 语句被注释掉。为什么?
(我找不到这个记录。)

Sub Test()
  Dim a1() As Integer
  ReDim a1(0 To 2)
  Erase a1
  Debug.Print a1(1)       ' Subscript out of range (Run-time error '9')
  Debug.Print LBound(a1)  ' Subscript out of range (Run-time error '9')
  Debug.Print UBound(a1)  ' Subscript out of range (Run-time error '9')
End Sub

我应该用 For i = LBound(a1) to UBound(a1): a1(i) = 0: Next i 替换 Erase 吗?

来自链接文档:

Erase frees the memory used by dynamic arrays. Before your program can refer to the dynamic array again, it must redeclare the array variable's dimensions by using a ReDim statement.


Erase 的行为对于 staticdynamic 数组是不同的。对于静态数组,该命令将所有成员重置为其默认值(数字为 0,字符串为空字符串)。对于动态数组,它会删除所有成员,情况就像您从未使用过 Redim.

在你的例子中,你有一个动态数组,没有必要使用 Erase。如果你想在使用后重置数组的所有值,只需发出另一个 Redim 语句,大小保持不变并不重要。除非您使用带有关键字 PreserveRedim,否则所有成员都使用默认值创建。以下语句可以解决问题:

ReDim a1(LBound(a1) To UBound(a1))

我不完全确定你想要实现什么,但是当你重新调整数组然后擦除它时,你不能指望返回一些结果(运行-时间错误说它不能显示上bound/lower 删除数组时绑定。

所以你应该先切换 Erase 然后再 Redim 它...但是在某种循环中使用 erase 会很好。

Sub Test()
  Dim a1() As Integer
  Erase a1 'no point erasing when it is not used yet
  ReDim a1(0 To 2)
  Debug.Print a1(1)       
  Debug.Print LBound(a1)  
  Debug.Print UBound(a1)  
End Sub

这是一个示例,您可以在循环结束时使用和擦除数组。

Sub Test_with_loop()

    Dim a1() As Integer, x As Byte
     
    For x = 0 To 10
        ReDim a1(0 To 2)
        a1(1) = x 'assign value in loop or something
    
        Debug.Print a1(1)        'print something
        Debug.Print LBound(a1)   'print something
        Debug.Print UBound(a1)   'print something
    
        Erase a1 'erase array from memory
    Next x 
End Sub