【问题标题】:Why am I getting subscript out of range error when trying to redim?为什么在尝试重新调整时出现下标超出范围错误?
【发布时间】:2016-06-09 23:54:08
【问题描述】:

我正在尝试创建一个在循环中添加单元的动态数组。 每次我尝试重新调整和添加一个单位时,都会收到以下错误:

下标超出范围

我的代码:

dim arr()
strSql = "SELECT item from dupEmail"
    Set rs = CurrentDb.OpenRecordset(strSql)
    rs.MoveFirst
    ReDim arr(0)
    Do While Not rs.EOF
        arr(UBound(arr, 1)) = rs.Fields(0)
        ReDim Preserve arr(1, UBound(arr, 1) + 1)
        rs.MoveNext
    Loop

我试过ReDim Preserve arr(0, UBound(arr, 0) + 1),但也没有用。

【问题讨论】:

  • 错误发生在哪一行?你为什么要重新调整呢?在循环之前查找记录集中的条目数并预先设置数组的长度。
  • 为什么不直接使用记录集呢?你试过 Redim 保存 arr(ubound(arr)+1)
  • redim行出现错误。感谢您的提示,但我必须这样做。请记住,这是对我的代码的简化。
  • @Nathan_Sav,是的。仍然得到同样的错误。
  • 不是单索引数组,还想把它改成多维数组吗?

标签: vba ms-access


【解决方案1】:

我认为发布建议的代码更容易:评论并未显示全部:您已经在 0 索引处 Redim,因此您需要为每条记录递增。它会在最后创建一个不必要的,删除它。

dim arr()
strSql = "SELECT item from dupEmail"

Set rs = CurrentDb.OpenRecordset(strSql)
rs.MoveFirst
ReDim arr(0)
Do While Not rs.EOF
    arr(UBound(arr)) = rs.Fields(0)
    ReDim Preserve arr(UBound(arr) + 1)
    rs.MoveNext
Loop
ReDim Preserve arr(UBound(arr) - 1)

或者简单地使用 rs.RecordCount 代替 Redim(0) 对所有记录进行 redim,并避免在循环中使用 Redim。你当然需要一个计数器。

【讨论】:

    【解决方案2】:
    ReDim arr(a, b)
    

    一样
    ReDim arr(0 To a, 0 To b)
    

    你想要的是

    ReDim arr(a To b)
    

    在您的情况下,您将 arr 调暗为长度为 1 的一维数组,ReDim arr(0)。然后您尝试将其重新调整为二维数组。如果您不使用Preserve,它工作得很好,但使用Preserve,它不知道将旧值放在哪里(我认为)并引发错误。

    因此,要解决您的问题,请将 ReDim Preserve arr(1, UBound(arr, 1) + 1) 替换为 ReDim Preserve arr(1 To UBound(arr, 1) + 1),但 cmets 中还提到了其他更可取的想法。请记住,“重新调整”可能很耗时。在最坏的情况下,程序必须分配新的(更大的)内存并在每次迭代中从旧位置复制所有内容。无论如何它可能不会引起注意,但在循环之前分配整个数组仍然是更好的做法。

    edit:哦,没注意到cmets中已经提到了。

    edit2:在非代表性测试中,循环内重新调光所用的时间大约是预先调光时间的 6 倍。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-13
      • 2014-05-19
      • 1970-01-01
      • 2015-05-27
      • 2016-03-07
      相关资源
      最近更新 更多