通过文件夹代码循环的下标超出范围

时间:2013-04-18 03:53:34

标签: excel excel-vba vba

我正在尝试使用以下代码遍历文件夹。但是,我一直在下标超出范围错误。任何人都可以解释我能解决这个问题的方法吗?

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

3 个答案:

答案 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)构造然后检查变量时,它似乎完全符合您的预期 - 但这是不可能的在使用上限和下限声明数组后重新生成数组。