我正在尝试使用以下代码遍历文件夹。但是,我一直在下标超出范围错误。任何人都可以解释我能解决这个问题的方法吗?
Sub LoopThroughFolder()
Const FileSpec As String = "*.xls"
Dim y As Integer
Dim MyFolder As String
Dim MyFile As String
Dim iDot As Integer
Dim FileRoot As String
Dim FileExt As String
Dim ArrayData() As Variant
For y = 2009 To 2030
ReDim Preserve ArrayData(y, 12)
MyFolder = ActiveWorkbook.Path & "\" & y & "\"
i = 1
MyFile = Dir(MyFolder & FileSpec)
Do While Len(MyFile) > 0
iDot = InStrRev(MyFile, ".")
If iDot = 0 Then
FileRoot = MyFile
FileExt = ""
Else
FileRoot = Left(MyFile, iDot - 1)
FileExt = Mid(MyFile, iDot - 1)
End If
MyFile = Dir
ArrayData(y, i) = FileRoot
MsgBox ArrayData(y, i)
i = i + 1
Loop
Next y
End Sub
答案 0 :(得分:4)
根据此msdn link,您只能在数组的最后一个维度上ReDim Preserve
,在您的情况下,您只能更改12
中的ReDim Preserve ArrayData(y, 12)
。更改数组参数的顺序将解决此问题。
答案 1 :(得分:0)
首先,正如@TheGreatCo所提到的,你只能重新构建数组的最后一个维度。
ReDim Preserve ArrayData(y, 12)
正在抛出错误,因为您正在尝试重新创建第一个维度。
尝试更改为:
ReDim Preserve ArrayData(12,y)
要限制i
,请将您的Loop
行更改为:
Loop While i <=12
但是,这仍然有点矫枉过正。虽然它可能不会导致任何错误,但它肯定是低效的。您不需要y
列(2030列!!!),因为您从未向ArrayData(12,1955)分配任何内容。
您需要修改迭代项目的方式并更有效地分配给数组。
我建议:
ReDim Preserve ArrayData(12,y-2009)
然后您需要更改:
ArrayData(i,y) = FileRoot
MsgBox ArrayData(i,y-2009)
答案 2 :(得分:0)
既然您知道y
的最大值是什么,为什么要使用ReDim
呢?这是非常低效的,因为它涉及重新定位所有数据,如果没有可用的额外(连续)空间,以及复制内容。相反,做
ArrayData(2009 To 2030, 1 To 12) As Variant
并且不要进行任何重新定标。
这并没有真正解决问题,因为i
的值实际上是无限增长的,而ReDim
从不考虑更改{{ 1}}维度(总是12)。
根据您的目的,您可以考虑使用“集合”。使用集合,您可以指定任何字符串作为索引;因此,您可以使用i
...
或者,声明具有初始尺寸(2,12)的Variant类型的数组。找到文件根目录时,将相应的年份分配给(1,i),将文件根目录分配给(2,i)。现在你有一个不包含大量空元素(高效)的数组,可以重新标注(沿第二维),并捕获原始数据的所有数据。实际上,您已经创建了自己的“稀疏数组”。
另外一个:
与我在上面的评论中提到的相反,当我尝试在Excel VBA中使用CStr(y)&"-"&CStr(i)
构造然后检查变量时,它似乎完全符合您的预期 - 但这是不可能的在使用上限和下限声明数组后重新生成数组。