2016-06-09 63 views
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, 1)) = rs.Fields(0) 
     ReDim Preserve arr(1, UBound(arr, 1) + 1) 
     rs.MoveNext 
    Loop 

我想ReDim Preserve arr(0, UBound(arr, 0) + 1)但没有工作。

+0

错误发生在哪一行?为什么你要反正redim?循环前查找记录集中的条目数,并事先设置数组的长度。 –

+0

为什么不直接使用记录集?你有没有试过Redim preserve arr(ubound(arr)+1) –

+0

这个错误发生在redim行上。谢谢你的提示,但我必须这样做。请记住,这是我的代码的简化。 – MJH

回答

1
ReDim arr(a, b) 

相同

ReDim arr(0 To a, 0 To b) 

你想要的是

ReDim arr(a To b) 

在你的情况暗淡改编为长度为1的一维数组ReDim arr(0)。然后,您尝试将它作为二维数组重新定义。如果你不使用Preserve工作得很好,但与Preserve它不知道在哪里把旧值(我认为)并抛出一个错误。

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

编辑:哦,没有注意到它已经在评论中提到。

edit2:在非代表性测试中,循环内的调光需要预先调光约6倍。

2

我认为更容易发布建议的代码:评论并未全部显示:您已经在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。你当然需要一个柜台。