“Subscript out of range” error when calling LBound

2019-07-16 03:46发布

问题:

The following code produces the error "Subscript out of range" and I do not know why. Can someone please explain?

    Dim errorc As Integer
    Dim myarray() As Variant


    errorc = 1

    If Len(Me.txt_Listnum) = 0 Then
    ReDim Preserve myarray(errorc)
    myarray(errorc) = "Numer Listy"
    errorc = errorc + 1
    End If

    If Len(Me.cbo_ByWho) = 0 Then
    ReDim Preserve myarray(errorc)
    myarray(errorc) = "Wystawione przez"
    errorc = errorc + 1
    End If

    If Len(Me.cbo_ForWho) = 0 Then
    ReDim Preserve myarray(errorc)
    myarray(errorc) = "Wystawione na"
    errorc = errorc + 1
    End If

    For i = LBound(myarray) To UBound(myarray)
        msg = msg & myarray(i) & vbNewLine
    Next i

    If errorc > 0 Then
       MsgBox "da" & msg

    End If

回答1:

Your code will fail if all of the form controls are populated and therefore myarray never gets ReDim'd. For an unititialized dynamic array,

Dim myarray() As Variant

(i.e., one that has not been subsequently sized with ReDim), calling LBound() or UBound() on it will fail with "Subscript out of range."



回答2:

My VB(A) is far away, but still. the (Re)Dim() method defines the size of the array; the index of the array goes from 0 to size-1. Therefore, when you do this :

errorc = 1

If Len(Me.txt_Listnum) = 0 Then
ReDim Preserve myarray(errorc)
myarray(errorc) = "Numer Listy"
errorc = errorc + 1
End If
  1. You redimension myarray to contain 1 element (ReDim Preserve myarray(errorc)). it will have only 1 index : 0
  2. you try to place something in index 1 (myarray(errorc) = "Numer Listy"), which will fail with the error message you mention.

So what you should to is organize things like this :

errorc = 0

If Len(Me.txt_Listnum) = 0 Then
    errorc = errorc + 1 'if we get here, there's 1 error more
    ReDim Preserve myarray(errorc) 'extend the array to the number of errors
    myarray(errorc-1) = "Numer Listy" 'place the error message in the last index of the array, which you could get using UBound() too
End If

EDIT

Following your remark, I had a look at this page. I'm a bit surprised. From where I see it UBound should return the size of the array -1, but from the examples given it seems it returns the size of the array, point. So, if the examples on that page are correct (and your error seems to indicate they are), you should write your loop this way :

For i = LBound(myarray) To UBound(myarray)-1
    msg = msg & myarray(i) & vbNewLine
Next i