Subscript out of Range after Erase

Viewed 125

The following minimal example crashes until the Erase statement is commented out. Why?
(I can't find this documented.)

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

Should I replace the Erase with For i = LBound(a1) to UBound(a1): a1(i) = 0: Next i?

2 Answers

From the linked documentation:

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.


The behavior of Erase is different for static and dynamic arrays. For static arrays, the command resets all members to their default value (0 for numbers, empty string for strings). For dynamic array, it removes all members, the situation is the same as if you never used a Redim.

In your case, where you have a dynamic array, there is no need to use Erase. If you want to reset all values of the array after using it, simply issue another Redim-statement, it doesn't matter if the size stays the same. Unless you use Redim with the keyword Preserve, all members are created with the default value. The following statement will do the trick:

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

I am not entirely sure what you are trying to achieve but when you ReDim array and then you erase it you cannot expect that some result is returned (Run-Time error says it cant display upper bound/lower bound when you deleted array.

So you should just switch Erase and then Redim it... But it would be good to use erase in some kind of loop.

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

So here is an example that you could use and erase array at end of loop.

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
Related