在 VBA 数组上调用 LBound() 或 UBound() 时出现“下标超出范围”错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21630396/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-12 01:48:41  来源:igfitidea点击:

"Subscript out of range" error when calling LBound() or UBound() on a VBA array

vbams-accessaccess-vba

提问by user3002600

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

回答by Gord Thompson

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

如果所有的表单控件都被填充,因此你的代码将失败,因此myarray永远不会被ReDim'd。对于一个单元化的动态数组,

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."

(即,随后没有用 调整大小的一个ReDim),调用LBound()UBound()将失败并显示“下标超出范围”。

回答by Laurent S.

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 :

我的 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. 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.
  1. 您将 myarray 重新定义为包含 1 个元素 ( ReDim Preserve myarray(errorc))。它将只有 1 个索引:0
  2. 您尝试将某些内容放在索引 1 ( myarray(errorc) = "Numer Listy") 中,这将失败并显示您提到的错误消息。

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 :

根据您的评论,我查看了此页面。我有点惊讶。从我看到的地方,UBound 应该返回数组的大小 -1,但从给出的示例来看,它似乎返回数组的大小,点。因此,如果该页面上的示例是正确的(并且您的错误似乎表明它们是正确的),您应该这样编写循环:

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