sans,
The following macro calls a custom subroutine I created awhile ago which is used to loop through all subfolders in a main folder and get all of the full file paths and names that meet a file extension criteria. In this case, I set the file extension criteria to be "xls*" to that it will pick up only Excel files (xls, xlsx, and xlsm). Then it uses that file's workbook name to rename the first sheet to be the same name as the workbook. In some cases, this may not be strictly possible due to sheet name character limit and illegal characters in the sheet name, but the macro will get it as close as possible (and in the majority of cases it should be an exact match). Just change the "C:\Test" (in red in the code) to the correct folder path of the main folder.
Sub tgr()
Dim ws As Worksheet
Dim arrFiles As Variant
Dim varFilePath As Variant
Dim strNameWS As String
Dim i As Long
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Set ws = Sheets.Add
GetAllFiles ws.Range("A1"), "C:\Test", "xls*", True
arrFiles = Application.Transpose(ws.Range("A1", ws.Cells(ws.Rows.Count, "A").End(xlUp)).Value)
ws.Delete
For Each varFilePath In arrFiles
strNameWS = Replace(Mid(varFilePath, InStrRev(varFilePath, "\") + 1), Mid(varFilePath, InStrRev(varFilePath, ".")), vbNullString)
For i = 1 To 7
strNameWS = Replace(strNameWS, Mid(":\/?*[]", i, 1), " ")
Next i
strNameWS = Trim(Left(WorksheetFunction.Trim(strNameWS), 31))
With Workbooks.Open(varFilePath)
.Sheets(1).Name = strNameWS
.Close True
End With
Next varFilePath
Application.DisplayAlerts = True
Application.ScreenUpdating = True
Set ws = Nothing
Erase arrFiles
End Sub
Here is the subroutine I created that is called in the above macro. It is a recursive subroutine (it calls itself) so it doesn't matter how many subfolders there are, nor how many subfolders each subfolder has, and so on:
Public Sub GetAllFiles(ByRef rngDest As Range, ByVal strFolderPath As String, Optional ByVal strExt As String = "*", Optional ByVal bCheckSubfolders As Boolean = False)
Dim FSO As Object
Dim oFile As Object
Dim oFolder As Object
Dim strFiles(1 To 65000) As String
Dim FileIndex As Long
FileIndex = 0
Set FSO = CreateObject("Scripting.FileSystemObject")
For Each oFile In FSO.GetFolder(strFolderPath).Files
If LCase(FSO.GetExtensionName(oFile.Path)) Like LCase(strExt) Then
FileIndex = FileIndex + 1
strFiles(FileIndex) = oFile.Path
End If
Next oFile
If FileIndex > 0 Then rngDest.Resize(FileIndex).Value = Application.Transpose(strFiles)
If bCheckSubfolders = True Then
Set rngDest = rngDest.Offset(FileIndex)
For Each oFolder In FSO.GetFolder(strFolderPath).SubFolders
GetAllFiles rngDest, oFolder.Path, strExt, True
Next oFolder
End If
Set FSO = Nothing
Erase strFiles
End Sub
Bookmarks