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
WritePdfFoldersAndFiles
procedure, carefully adjust the arguments of the called procedure (WriteFoldersAndFiles
) in it.
- To learn about the
Dir
parameters (switches) visit the Microsoft Docs' dir
page.
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