Write a List of Files to a Worksheet
- Copy the code to a standard module, e.g. Module1, in the workbook with the worksheet you plan to write to.
- Then, before running the one-liner WritePdfFoldersAndFilesprocedure, carefully adjust the arguments of the called procedure (WriteFoldersAndFiles) in it.
- To learn about the Dirparameters (switches) visit the Microsoft Docs'dirpage.
Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose:      From a folder ('"C:\"') and all its subfolders ('/s'), returns
'               all PDF ("*.pdf") file names (second column) and their
'               folder paths (first column) in two columns of worksheet 'Sheet1'
'               in the workbook containing this code, starting with cell 'A2'.
'               The '/b' switch is necessary to get the file paths.
'               The 'a-d' switch is necessary to exclude directories.
' Remarks:      If you select all files (*.*) on your system drive (e.g. 'C:\'),
'               there may be a different number of files on each run due to
'               newly created logs, temp files, or whatnot.
' Calls:        'WriteFoldersAndFiles'
'                   'ArrFilePaths'
'                   'GetFoldersAndFiles'
'                       'SplitStringByLastCharToRow'
'                   'WriteDataSimple'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub WritePdfFoldersAndFiles()
     
    ' Adjust (play with) the values in this line:
    WriteFoldersAndFiles "C:\", "*.pdf", "/s/b/a-d", "Sheet1", "A2"
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose:      Writes a list of folder paths and file names to two columns
'               of a worksheet in the workbook containing this code.
' Calls:        'ArrFilePaths'
'               'GetFoldersAndFiles'
'                   'SplitStringByLastCharToRow'
'               'WriteDataSimple'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub WriteFoldersAndFiles( _
        ByVal FolderPath As String, _
        Optional ByVal DirPattern As String = "*.*", _
        Optional ByVal DirSwitches As String = "/s/b/a-d", _
        Optional ByVal WorksheetName As String = "Sheet1", _
        Optional ByVal FirstCellAddress As String = "A1")
    Const ProcName As String = "WriteFoldersAndFiles"
    On Error GoTo ClearError
    
    Const tf As String = "0.0000"
    Dim t As Double, tt As Double, tc As Double, ti As Double
    ti = Timer: t = ti
    ' Write the file paths to an array ('fPaths').
    Dim fPaths() As String
    fPaths = ArrFilePaths(FolderPath, DirPattern, DirSwitches)
    
    tc = Timer: Debug.Print "ArrFilePaths...          " _
        & Format(tc - t, tf) & "(" & Format(tc - ti, tf) & ")": t = tc
    ' Split the file paths by the last path separator, to folder paths
    ' and file names, into a 2D one-based two-column array ('Data').
    Dim Data As Variant: Data = GetFoldersAndFiles(fPaths)
    'Erase fPaths ' probably nothing to gain
    
    tc = Timer: Debug.Print "GetFoldersAndFiles...    " _
        & Format(tc - t, tf) & "(" & Format(tc - ti, tf) & ")": t = tc
    ' Write the values from the 2D array to a worksheet in the workbook
    ' containing this code ('ThisWorkbook').
    WriteDataSimple ThisWorkbook.Worksheets(WorksheetName) _
        .Range(FirstCellAddress), Data
    
    tc = Timer: Debug.Print "WriteDataSimple...       " _
        & Format(tc - t, tf) & "(" & Format(tc - ti, tf) & ")": t = tc
ProcExit:
    Exit Sub
ClearError:
    Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
              & "    " & "Run-time error '" & Err.Number & "':" & vbLf _
              & "    " & Err.Description
    Resume ProcExit
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose:      Returns the file paths of the files in a folder in an array.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function ArrFilePaths( _
    ByVal FolderPath As String, _
    Optional ByVal FilePattern As String = "*.*", _
    Optional ByVal DirSwitches As String = "/s/b/a-d") _
As Variant
    Const ProcName As String = "ArrFilePaths"
    On Error GoTo ClearError
    
    Dim pSep As String: pSep = Application.PathSeparator
    If Right(FolderPath, 1) <> pSep Then FolderPath = FolderPath & pSep
    Dim ExecString As String ' '%comspec%' or 'cmd.exe' ?
    ExecString = "%comspec% /c Dir """ _
        & FolderPath & FilePattern & """ " & DirSwitches
    ArrFilePaths = Split(CreateObject("WScript.Shell") _
        .Exec(ExecString).StdOut.ReadAll, vbCrLf)
ProcExit:
    Exit Function
ClearError:
    Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
              & "    " & "Run-time error '" & Err.Number & "':" & vbLf _
              & "    " & Err.Description
    Resume ProcExit
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose:      From an array containing file paths, returns
'               the folder paths and the file names in two columns
'               of a 2D one-based two-column array.
' Calls:        'SplitStringByLastCharToRow'.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function GetFoldersAndFiles( _
    ByVal FilePaths As Variant) _
As Variant
    Const ProcName As String = "GetFoldersAndFiles"
    On Error GoTo ClearError
    Dim pSep As String: pSep = Application.PathSeparator
    Dim nLB As Long: nLB = LBound(FilePaths)
    Dim nUB As Long: nUB = UBound(FilePaths)
    
    Dim Data() As String: ReDim Data(1 To nUB - nLB, 1 To 2)
    
    Dim r As Long
    Dim n As Long
    
    For n = nLB To nUB - 1 ' last item is an empty string
        r = r + 1
        SplitStringByLastCharToRow Data, r, FilePaths(n), pSep
    Next n
    
    GetFoldersAndFiles = Data
ProcExit:
    Exit Function
ClearError:
    Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
              & "    " & "Run-time error '" & Err.Number & "':" & vbLf _
              & "    " & Err.Description
    Resume ProcExit
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose:      Writes the values from a 2D one-based array ('Data') to a range
'               defined by its first cell ('FirstCell') and by the size
'               of the array. Optionally (by default), previously
'               clears the columns (preserving the data above (e.g. headers)).
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub WriteDataSimple( _
        ByVal FirstCell As Range, _
        ByVal Data As Variant, _
        Optional ByVal DoClearContents As Boolean = True)
    Const ProcName As String = "WriteDataSimple"
    On Error GoTo ClearError
    
    With FirstCell.Resize(, UBound(Data, 2))
        If DoClearContents Then
            .Resize(.Worksheet.Rows.Count - .Row + 1).Clear
        End If
        .Resize(UBound(Data, 1)).Value = Data
    End With
ProcExit:
    Exit Sub
ClearError:
    Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
              & "    " & "Run-time error '" & Err.Number & "':" & vbLf _
              & "    " & Err.Description
    Resume ProcExit
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose:      Splits a string ('SplitString') by the last occurrence
'               of a character ('SplitChar') and writes the two split strings
'               to the first two columns in a row ('DataRow')
'               of a 2D one-based array ('Data').
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub SplitStringByLastCharToRow( _
        ByRef Data As Variant, _
        ByVal DataRow As Long, _
        ByVal SplitString As String, _
        ByVal SplitChar As String)
    Const ProcName As String = "SplitStringByLastCharToRow"
    On Error GoTo ClearError
    
    Dim lcPos As Long: lcPos = InStrRev(SplitString, SplitChar)
    If lcPos = 0 Then Exit Sub
    
    Data(DataRow, 1) = Mid(SplitString, 1, lcPos - 1)
    Data(DataRow, 2) = Mid(SplitString, lcPos + 1, Len(SplitString) - lcPos)
'    Data(DataRow, 1) = Left(SplitString, lcPos - 1)
'    Data(DataRow, 2) = Right(SplitString, Len(SplitString) - lcPos)
ProcExit:
    Exit Sub
ClearError:
    Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
              & "    " & "Run-time error '" & Err.Number & "':" & vbLf _
              & "    " & Err.Description
    Resume ProcExit
End Sub