从仅 2-3 层深的子文件夹中提取文件信息

File info pull from sub folders only 2-3 levels deep

我目前有一个代码允许用户选择一个文件夹,然后该代码将提取该文件夹中文件的文件信息,但不提取子文件夹中任何文件的文件信息。我有 7 级子文件夹,其中包含大约 140,000 个文件。我想知道是否有一种方法可以让我只提取 2-3 级子文件夹中的文件信息,而不仅仅是 1 级,而不是来自所有 7 级。感谢您的帮助。

我认为 "pasting formula in column 3" 部分与此问题无关。

可能重要的部分是 "Picking a folder" 和 "Running through each file in the selected folder"

Sub Compile3()
  Dim oShell As Object
  Dim oFile As Object
  Dim oFldr As Object
  Dim lRow As Long
  Dim iCol As Integer
  Dim vArray As Variant
  vArray = Array(10, 0, 1, 156, 2, 4, 144, 146, 183, 185)

  Set oShell = CreateObject("Shell.Application")

  Dim iRow As Long
   iRow = Cells.find(What:="*", SearchOrder:=xlRows, SearchDirection:=xlPrevious, LookIn:=xlValues).Row
   lRow = iRow
'----------------------Picking a folder-------------------------------------


  With Application.FileDialog(msoFileDialogFolderPicker)
    .title = "Select the Folder..."
    If .Show Then
      Set oFldr = oShell.Namespace(.SelectedItems(1))
      With oFldr

      'Don't show update on the screen until the macro is finished
      Application.EnableEvents = False

'---------------Column header information-----------------------------------

        For iCol = LBound(vArray) To UBound(vArray)
          If lRow = 2 Then
            Cells(lRow, iCol + 4) = .getdetailsof(.items, vArray(iCol))
          Else
            Cells(lRow, iCol + 4) = "..."
          End If             
        Next iCol
'---------------Running through each file in the selected folder------------   
        For Each oFile In .items
          lRow = lRow + 1

          For iCol = LBound(vArray) To UBound(vArray)                   
             Cells(lRow, iCol + 4) = .getdetailsof(oFile, vArray(iCol))    
          Next iCol
 ' ---------------Pasting formula in column 3 -----------------------------             
               If lRow < 4 Then
                        Cells(lRow, 3).Formula = "=IFERROR(VLOOKUP(D3,$A:$B,2,FALSE),""User Not Found"")"

           Else
                    Cells((lRow - 1), 3).Copy
                    Cells(lRow, 3).PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
                    Cells(lRow, 3).PasteSpecial Paste:=xlPasteFormulas, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
                    Application.CutCopyMode = False                                       

           End If              
'------------------------------------------------------------------------------            

        Next oFile
      End With
    End If
Application.EnableEvents = True
  End With  

End Sub

file system object 可以为您做到这一点。

在此示例中,代码 returns 您 C:\ 驱动器上的每个子文件夹。

' Returns every folder under the C:\.
Sub CrawlFolder()
    Dim fso As FileSystemObject     ' Access the Windows file system.
    Dim folder As folder            ' Used to loop over folders.


    Set fso = New FileSystemObject
    For Each folder In fso.GetFolder("C:\").SubFolders

        Debug.Print folder.Name
    Next
End Sub

要查看结果,请确保您已打开 Immediate window(查看 >> 立即Window).

要使用文件系统对象,您需要添加引用 (Tools >> References >> Windows 脚本宿主对象模型).

您可以添加第二个For Each Loop来查看文件:

' Returns every folder under the C:\.
Sub CrawlFolder()
    Dim fso As FileSystemObject     ' Access the Windows file system.
    Dim folder As folder            ' Used to loop over folders.
    Dim file As file                ' Used to loop over files.

    Set fso = New FileSystemObject
    For Each folder In fso.GetFolder("C:\").SubFolders

        For Each file In folder.Files

            Debug.Print file.Name
        Next
    Next
End Sub

我修改了您的代码以使用数组并使用递归函数return 文件夹文件信息。


Sub ProcessFolder()
    Dim FolderPath As String
    Dim results As Variant
    Dim Target As Range

    FolderPath = getFileDialogFolder

    If Len(FolderPath) = 0 Then Exit Sub

    getFolderItems FolderPath, results
    CompactResults results

    With Worksheets("Sheet1")
        .Range("C3", .Range("I" & Rows.Count).End(xlUp)).ClearContents
        Set Target = .Range("C3")
        Set Target = Target.EntireRow.Cells(1, 4)
        Target.Resize(UBound(results), UBound(results, 2)).Value = results
        Target.Offset(1, -1).Resize(UBound(results) - 1).Formula = "=IFERROR(VLOOKUP(D3,$A:$B,2,FALSE),""User Not Found"")"
    End With

End Sub

Sub CompactResults(ByRef results As Variant)
    Dim data As Variant
    Dim x As Long, x1 As Long, y As Long, y1 As Long

    ReDim data(1 To UBound(results) + 1, 1 To UBound(results(0)) + 1)

    For x = LBound(results) To UBound(results)
        x1 = x1 + 1
        y1 = 0
        For y = LBound(results(x)) To UBound(results(x))
            y1 = y1 + 1
            data(x1, y1) = results(x)(y)
        Next
    Next

    results = data
End Sub

Function getFileDialogFolder() As String
    With Application.FileDialog(msoFileDialogFolderPicker)
        .Title = "Select the Folder..."
        .AllowMultiSelect = False
        If .Show Then
            getFileDialogFolder = .SelectedItems(1)
        End If
    End With
End Function

Sub getFolderItems(FolderPath As String, ByRef results As Variant, Optional MaxLevels As Long = 1, Optional oShell As Object, Optional Level As Long)
    Dim oFile As Object, oFldr As Object

    If oShell Is Nothing Then
        ReDim results(0)
        Set oShell = CreateObject("Shell.Application")
    End If

    If Not IsEmpty(results(UBound(results))) Then ReDim Preserve results(UBound(results) + 1)

    Set oFldr = oShell.Namespace(CStr(FolderPath))

    results(UBound(results)) = getFolderFileDetailArray(oFldr.Self, oFldr)
    results(UBound(results))(1) = oFldr.Self.Path
    For Each oFile In oFldr.Items
        ReDim Preserve results(UBound(results) + 1)
        If oFldr.getDetailsOf(oFile, 2) = "File folder" Then
            If Level < MaxLevels Then
                getFolderItems oFile.Path, results, MaxLevels, oShell, Level + 1
            End If
        End If
        results(UBound(results)) = getFolderFileDetailArray(oFile, oFldr)
    Next oFile

End Sub

Function getFolderFileDetailArray(obj As Object, oFldr As Object) As Variant
    Dim iCol As Integer
    Dim vDetailSettings As Variant
    vDetailSettings = Array(10, 0, 1, 156, 2, 4, 144, 146, 183, 185)

    For iCol = LBound(vDetailSettings) To UBound(vDetailSettings)
        vDetailSettings(iCol) = oFldr.getDetailsOf(obj, vDetailSettings(iCol))
    Next iCol

    getFolderFileDetailArray = vDetailSettings

End Function