I'm trying to write VBA code that does the following:
- Finds all *.xlsx and *.xlsm files in specified path and subdirectories
- Opens each one read-only
- Copies the contents to the current spreadsheet, then closes file
- Loops through all files
The closest I've been able to get is derived from Loop Through All Subfolders Using VBA, where FolderPath is "C:\Path\To\Folder":
Dim fso, oFolder, oSubfolder, oFile, queue As Collection
Set fso = CreateObject("Scripting.FileSystemObject")
Set queue = New Collection
queue.Add fso.GetFolder(FolderPath)
Do While queue.Count > 0
Set oFolder = queue(1)
queue.Remove 1
For Each oSubfolder In oFolder.SubFolders
queue.Add oSubfolder
Next oSubfolder
For Each oFile In oFolder.Files
Length = InStrRev(oFile, "\")
oFileWB = Right(oFile, Len(oFile) - Length)
'Open the given .xls* file read-only and suppress link update prompt
Workbooks.Open FileName:=oFile, ReadOnly:=True, UpdateLinks:=False
'Get current first empty row of database as first target row
ftr = ThisWorkbook.Worksheets("Database").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
'Copy range from target sheet, from hardcoded cell A7 to AE in the bottom-most occupied row
Workbooks(oFileWB).Sheets("Target Sheet").Range("A7:AE" & Workbooks(oFileWB).Sheets("Target Sheet").Cells(Rows.Count, 1).End(xlUp).Row).Copy
'Paste above range into the first empty cell of the database
ThisWorkbook.Worksheets("Database").Range(ThisWorkbook.Worksheets("Database").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Address).PasteSpecial xlPasteValues
'Get last row of current database after copying data
ltr = ThisWorkbook.Worksheets("Database").Cells(Rows.Count, 1).End(xlUp).Row
'Copy date and filepath of sheet into all rows
ThisWorkbook.Worksheets("Database").Range("AF" & ftr & ":AF" & ltr).Value = Now()
ThisWorkbook.Worksheets("Database").Range("AG" & ftr & ":AG" & ltr).Value = oFile
'Close current file and suppress save changes prompt
Workbooks(oFileWB).Close savechanges:=False
Next oFile
Loop
This works when nothing is open in those directories.
When one of the files is locked, it starts scanning files in "C:" instead of "C:\Path\To\Folder". This gives a permission error because it tries to open hiberfile.sys. This is a critical problem because this script (a) needs to act in an entirely read-only manner, and (b) files in these directories may be locked at any given time.
Also as a lesser issue - how can I restrict it to opening *.xlsx and *.xlsm files?