2016-06-09 20 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。你當然需要一個櫃檯。