如何从VBA中的子文件夹计算工作簿中的行数?

时间:2014-03-06 16:18:16

标签: excel vba excel-vba

我试图将行数计入某些文件夹和子文件夹中的文件。文件夹和子文件夹路径以G列写入。

Sub CountRows()
    Dim wbSource As Workbook, wbDest As Workbook
    Dim wsSource As Worksheet, wsDest As Worksheet
    Dim strFolder As String, strFile As String
    Dim lngNextRow As Long, lngRowCount As Long
    Dim LastRow
    Dim cl As Range

    Application.ScreenUpdating = False

    Set wbDest = ActiveWorkbook

    Set wsDest = wbDest.ActiveSheet

    LastRow = wsDest.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row

    For Each cl In wsDest.Range("G11:G" & LastRow)
        strFolder = cl.Value
        strFile = Dir(strFolder & "/")
        lngNextRow = 11

        Do While Len(strFile) > 0
            Set wbSource = Workbooks.Open(Filename:=strFolder & "/" & strFile)
            Set wsSource = wbSource.Worksheets(1)
            lngRowCount = wsSource.UsedRange.Rows.Count

            wsDest.Cells(lngNextRow, "F").Value = lngRowCount - 1
            wbSource.Close savechanges:=False
            lngNextRow = lngNextRow + 1

            strFile = Dir

        Loop
    Next cl
...

结果必须插入到F列中。也许有人可以解释一下,这个循环有什么问题,因为每个文件中的行数在F列中按目录数重复。

例如,如果我有一个包含3个文件的文件夹,则在GI列中将有3个目录(3个目录中的每个目录3个文件C:\ Users \ Desktop \ vba_files \等),然后我将获得3个数字列F是文件夹C:\ Users \ Desktop \ vba_files \中每个工作簿中的行数,但每个计数重复3次(按目录数)。

它看起来如下:

enter image description here

1 个答案:

答案 0 :(得分:1)

代码中的逻辑存在问题。首先,列G包含每个文件的条目,因此对于包含3个文件的文件夹,有3个重复的行。但是Do While循环为当前目录中的每个文件返回一个长度(因为你一直调用Dir没有参数)。然后For Each循环移动到G列中的下一个单元格,它再次包含相同的目录,Do While循环再次启动,您在F列中再获得3个条目。

我不确定为什么你会想要从列G开始重复这些重复,但是如果你这样做,那么你只需要一个循环来运行G列中的每个单元格,并检查目录是否每次都改变了。下面的代码执行此操作:

Sub CountRows()
    Dim wbSource As Workbook, wbDest As Workbook
    Dim wsSource As Worksheet, wsDest As Worksheet
    Dim strFolder As String, strFile As String
    Dim lngNextRow As Long, lngRowCount As Long
    Dim LastRow
    Dim cl As Range

    'Application.ScreenUpdating = False

    Set wbDest = ActiveWorkbook
    Set wsDest = wbDest.ActiveSheet

    LastRow = wsDest.Cells(wsDest.rows.count,7).end(xlUp).Row
    lngNextRow = 11
    strFolder = ""

    For Each cl In wsDest.Range("G11:G" & LastRow)
            If cl.Value <> strFolder Then
                    strFolder = cl.Value
                    strFile = Dir(strFolder & "/*.xl*")
            Else
                    strFile = Dir
            End If

            If Len(strFile) > 0 Then
                    Set wbSource = Workbooks.Open(Filename:=strFolder & "/" & strFile)
                    Set wsSource = wbSource.Worksheets(1)
                    lngRowCount = wsSource.UsedRange.Rows.Count

                    wsDest.Cells(lngNextRow, "F").Value = lngRowCount - 1
                    wbSource.Close savechanges:=False
                    lngNextRow = lngNextRow + 1
            End If
    Next cl
End Sub

请注意,如果目录中的文件数大于G列中相应条目的数量,则会忽略额外文件。

我在第一次调用Dir()时添加了一个过滤器,仅提取Excel文件。我还将LastRow的计算方式更改为一种更安全的方式(如果G中最后一个单元格的右下方有任何数据,则代码会给出错误的结果。)

实现这样的事情的一种更简洁的方法可能是:

  • 输入只是一个没有重复的目录列表
  • 循环输入
  • 为每个输入单元输出所有文件并在单独的输出表上计数

然后你可以拿起每个文件夹中的许多文件,而不必在G列中获得正确的条目数。