【问题标题】:Cycle through sub-folders and files in a user-specified root directory [duplicate]循环浏览用户指定的根目录中的子文件夹和文件[重复]
【发布时间】:2012-12-24 02:52:19
【问题描述】:

我通过单个文件的循环脚本工作正常,但我现在需要它来查看/查找多个目录。我被卡住了……

事情发生的顺序:

  • 提示用户选择他们需要的根目录
  • 我需要脚本来查找该根目录中的所有文件夹
  • 如果脚本找到一个,它会打开第一个(所有文件夹,因此没有针对文件夹的特定搜索过滤器)
  • 打开后,我的脚本将遍历文件夹中的所有文件并执行它需要执行的操作
  • 完成后,它会关闭文件、关闭目录并移至下一个目录,等等。
  • 循环直到所有文件夹都被打开/扫描

这就是我所拥有的,它不起作用,我知道是错误的:

MsgBox "Please choose the folder."
Application.DisplayAlerts = False
With Application.FileDialog(msoFileDialogFolderPicker)
    .InitialFileName = "\\blah\test\"
    .AllowMultiSelect = False
    If .Show <> -1 Then MsgBox "No folder selected! Exiting script.": Exit Sub
    CSRootDir = .SelectedItems(1)
End With
folderPath = Dir(CSRootDir, "\*")

Do While Len(folderPath) > 0
    Debug.Print folderPath
    fileName = Dir(folderPath & "*.xls")
    If folderPath <> "False" Then
        Do While fileName <> ""
            Application.ScreenUpdating = False
            Set wbkCS = Workbooks.Open(folderPath & fileName)

            --file loop scripts here

        Loop  'back to the Do
Loop    'back to the Do

最终代码。它循环遍历每个子目录中的所有子目录和文件。

Dim FSO As Object, fld As Object, Fil As Object
Dim fsoFile As Object 
Dim fsoFol As Object 
Dim fileName As String

    MsgBox "Please choose the folder."
    Application.DisplayAlerts = False
    With Application.FileDialog(msoFileDialogFolderPicker)
         .InitialFileName = "\\blah\test\"
         .AllowMultiSelect = False
         If .Show <> -1 Then MsgBox "No folder selected! Exiting script.": Exit Sub
         folderPath = .SelectedItems(1)
    End With

    If Right(folderPath, 1) <> "\" Then folderPath = folderPath + "\"
         Set FSO = CreateObject("Scripting.FileSystemObject")
         Set fld = FSO.getfolder(folderPath)
    If FSO.folderExists(fld) Then
         For Each fsoFol In FSO.getfolder(folderPath).subfolders
              For Each fsoFile In fsoFol.Files
                   If Mid(fsoFile.Name, InStrRev(fsoFile.Name, ".") + 1) = "xls" Then
    fileName = fsoFile.Name
    Application.ScreenUpdating = False
    Set wbkCS = Workbooks.Open(fsoFile.Path)

    'My file handling code


                End If
              Next
         Next
    End If

【问题讨论】:

标签: excel vba


【解决方案1】:

您可能会发现使用FileSystemObject 会更容易,类似这样的东西

这会将文件夹/文件列表转储到Immediate window

Option Explicit

Sub Demo()
    Dim fso As Object 'FileSystemObject
    Dim fldStart As Object 'Folder
    Dim fld As Object 'Folder
    Dim fl As Object 'File
    Dim Mask As String
    
    Set fso = CreateObject("scripting.FileSystemObject") ' late binding
    'Set fso = New FileSystemObject 'or use early binding (also replace Object types)
    
    Set fldStart = fso.GetFolder("C:\Your\Start\Folder") '-- use your FileDialog code here

    Mask = "*.xls"
    Debug.Print fldStart.Path & "\"
    ListFiles fldStart, Mask
    For Each fld In fldStart.SubFolders
        ListFiles fld, Mask
        ListFolders fld, Mask
    Next
End Sub


Sub ListFolders(fldStart As Object, Mask As String)
    Dim fld As Object 'Folder
    For Each fld In fldStart.SubFolders
        Debug.Print fld.Path & "\"
        ListFiles fld, Mask
        ListFolders fld, Mask
    Next

End Sub

Sub ListFiles(fld As Object, Mask As String)
    Dim fl As Object 'File
    For Each fl In fld.Files
        If fl.Name Like Mask Then
            Debug.Print fld.Path & "\" & fl.Name
        End If
    Next
End Sub

【讨论】:

  • 我会处理这个,看看能不能做到。谢谢克里斯!!
  • 是否可以将 fso.GetFolder 的路径分配给变量?我正在使用网络驱动器,因此 CSRootDir 是我的 .SelectedItem 变量。我回家后会做更多的研究,但只是想知道你是否知道答案。谢谢
  • 当然。只需使用您现有的代码获取根目录并将其传递给 fso
  • 克里斯,我最终修改了你的代码(我将发布),但你使用 FSO 肯定让我走上了正确的轨道。谢谢!
  • 我不得不说克里斯 - 这帮助我节省了大约 10 亿小时的手动搜索电子表格的时间。再次感谢!!
【解决方案2】:
Sub MoFileTrongCacFolder()

    Dim FSO As Object, fld As Object, Fil As Object
    Dim fsoFile As Object
    Dim fsoFol As Object
    Dim fileName As String
    Dim folderPath As String
    Dim wbkCS As Object

    MsgBox "Please choose the folder."
    Application.DisplayAlerts = False
    With Application.FileDialog(msoFileDialogFolderPicker)
        .InitialFileName = "\\blah\test\"
        .AllowMultiSelect = False
        If .Show <> -1 Then MsgBox "No folder selected! Exiting script.": Exit Sub
        folderPath = .SelectedItems(1)
    End With

    If Right(folderPath, 1) <> "\" Then folderPath = folderPath + "\"
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set fld = FSO.getfolder(folderPath)
    If FSO.folderExists(fld) Then
        For Each fsoFol In FSO.getfolder(folderPath).subfolders
            For Each fsoFile In fsoFol.Files
                If Mid(fsoFile.Name, InStrRev(fsoFile.Name, ".") + 1) = "xls" Then
                    fileName = fsoFile.Name
                    Application.ScreenUpdating = False
                    Set wbkCS = Workbooks.Open(fsoFile.Path)

                    'My file handling code


                End If
            Next
        Next
    End If
End Sub

【讨论】:

    【解决方案3】:

    这是一个 VBA 解决方案,不使用外部对象。

    由于Dir() 函数的限制,您需要一次获取每个文件夹的全部内容,而不是在使用递归算法进行爬网时。

    Function GetFilesIn(Folder As String) As Collection
      Dim F As String
      Set GetFilesIn = New Collection
      F = Dir(Folder & "\*")
      Do While F <> ""
        GetFilesIn.Add F
        F = Dir
      Loop
    End Function
    
    Function GetFoldersIn(Folder As String) As Collection
      Dim F As String
      Set GetFoldersIn = New Collection
      F = Dir(Folder & "\*", vbDirectory)
      Do While F <> ""
        If GetAttr(Folder & "\" & F) And vbDirectory Then GetFoldersIn.Add F
        F = Dir
      Loop
    End Function
    
    Sub Test()
      Dim C As Collection, F
    
      Debug.Print
      Debug.Print "Files in C:\"
      Set C = GetFilesIn("C:\")
      For Each F In C
        Debug.Print F
      Next F
    
      Debug.Print
      Debug.Print "Folders in C:\"
      Set C = GetFoldersIn("C:\")
      For Each F In C
        Debug.Print F
      Next F
    End Sub
    

    【讨论】:

    • dir的主要问题是不支持网络路径(以\开头)...
    猜你喜欢
    • 2017-07-22
    • 1970-01-01
    • 2010-12-20
    • 2017-07-10
    • 2019-05-28
    • 2011-10-04
    • 1970-01-01
    • 2015-12-07
    相关资源
    最近更新 更多