在VBA阵列上调用LBound()或UBound()时,“下标超出范围”错误

时间:2014-02-07 14:36:15

标签: vba ms-access access-vba

以下代码产生错误“下标超出范围”,我不知道为什么。有人可以解释一下吗?

    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

2 个答案:

答案 0 :(得分:6)

如果填充了所有表单控件,则代码将失败,因此myarray永远不会获得ReDim。对于单元化动态数组,

Dim myarray() As Variant

(即,之后未使用ReDim调整大小的内容),在其上调用LBound()UBound()将失败,并且“下标超出范围。”

答案 1 :(得分:0)

我的VB(A)很远,但仍然。 (Re)Dim()方法定义数组的大小;数组的索引从0到size-1。因此,当您这样做时:

errorc = 1

If Len(Me.txt_Listnum) = 0 Then
ReDim Preserve myarray(errorc)
myarray(errorc) = "Numer Listy"
errorc = errorc + 1
End If
  1. 你重新定义myarray以包含1个元素(ReDim Preserve myarray(errorc))。它只有1个索引:0
  2. 您尝试在索引1中放置一些内容(myarray(errorc) = "Numer Listy"),这会因您提及的错误消息而失败。
  3. 所以你应该做的是组织这样的事情:

    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
    

    修改

    在你的评论之后,我看了this page。我有点惊讶。从我看到的地方UBound应该返回数组-1的大小,但是根据给出的示例,它似乎返回数组的大小,指向。因此,如果该页面上的示例是正确的(并且您的错误似乎表明它们是正确的),那么您应该以这种方式编写循环:

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