Codes:
Rudi's Code
Sub ReplaceInAllSubFoldersRudisQing()
'' http://www.excelforum.com/excel-prog...ubfolders.html
Code:
' Rudi http://www.eileenslounge.com/viewtopic.php?f=27&t=22499
Sub ReplaceInAllSubFoldersQing()
Rem 1Q) Some Worksheets and General Variables Info
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets.Item(1) 'Worksheets("RudyMSRQueue") 'CHANGE TO SUIT YOUR WORKSHEET
Dim strDefpath As String: Let strDefpath = ThisWorkbook.Path ' Any Path to Folder to test this code! here we simply use the Path where the File with this code in is
Dim strDefFldr As String: Let strDefFldr = "EileensFldr" 'Just for an initial suggestion
Rem 2Q) Get Folder Info ( Using VBA Application.FileDialog(msoFileDialogFolderPicker) Property )
Dim strWB As String
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Folder Select "
.AllowMultiSelect = False
If .Show <> -1 Then
Exit Sub
End If
Let strWB = .SelectedItems(1) & "\"
End With
Rem 3Q) Microsoft Scripting Runtime Library
'Dim FSO As Object: Set FSO = CreateObject("Scripting.FileSystemObject")'Late Binding
Dim FSO As Scripting.FileSystemObject 'Early Binding alternative activate a reference to the Microsoft Scripting Runtime Library in the Tools > References menu of VBE.
Set FSO = New Scripting.FileSystemObject
Rem 4Q)'Some variables for Positon of Things
Dim rCnt As Long, clmLvl As Long: Let clmLvl = 1: Let rCnt = -1 'rowCount is genaraly increase for a new entry, Column "level" is intended to give an indication of how far down ( to he right ) you are in the Folder chain. Ste to 1 for the first mainn Initial Folder.
Dim CurrentLvlCnt As Long: CurrentLvlCnt = 1 'Count of the Number of Folders in the Folder level currently beig run through.
Dim NxtLvlCnt As Long 'Count of the Number of Folders in the next level
Dim queue As Collection
Set queue = New Collection
queue.Add FSO.GetFolder(strWB) 'Main Folder Put at position 1 of Queue'''''
Dim celTL As Range: Set celTL = ws.Range("A1") 'Top left of where Listing should go
'Application.ScreenUpdating = False
Rem 5Q) Main loop. Do While Queue is not Empty effectivelly goes through all Folders
Dim oFile As Variant, oFolder As Variant, oSubfolder As Variant ' Can also be variant Types or Objects. - Must be for Late Binding
Do While queue.Count > 0 'Main Loop. Does as many times as there are things ( Folders here ) stacked in the Queue========
Set oFolder = queue(1) 'Next Folder .... effectively
queue.Remove 1 'de-queue'......"taken" from start of Queue. ( Actually it is assigned to a variable, then removed from the Queue, which probably just has the Pointer to it.
CurrentLvlCnt = CurrentLvlCnt - 1 'de-the count for numbers in in this current Folder level
''''''''Doing Stuff For the Folder
rCnt = rCnt + 2 'Move on a line and a spare Line for every Folder Entry
celTL.Cells(rCnt, 1).Value = oFolder.Path: celTL.Cells(rCnt, clmLvl).Offset(0, 1).Value = oFolder.Name 'Cell poroperty of Top Left Cell Range Object uset to position output.
''''''''End Doing Stuff for each Folder
'5Qa) Add any Sub Folders from current Folder at end of queue
For Each oSubfolder In oFolder.SubFolders 'For as many ( if any ) Sub Folders In the Current Folder
queue.Add oSubfolder 'en-queue.. add the Sub Folder on at the end of the Queue
NxtLvlCnt = NxtLvlCnt + 1 'en-the count of the Folders in the next Level..Increase our count of the Folders in the Next folder level
Next oSubfolder
'5b) Doing Stuff for every file in current folder
For Each oFile In oFolder.Files
'''''''Doing Stuff for Each File here
If InStr(1, oFile.Name, ".xls") > 0 Then 'Option to select only if .xls ( or .xlsx or .xlsm ) type files
rCnt = rCnt + 1
celTL.Cells(rCnt, clmLvl).Offset(0, 1).Value = oFile.Name
On Error GoTo ErrHdlr 'In case problem opening file for example
'Set wbk = Workbooks.Open(oFile)
'wbk.Close SaveChanges:=True
Else: End If
'''''''End Doing Stuff for Each File
NxtoFile: Next oFile ' Spring Point after error handler so as to go on to next File after the File action that errored
'5Qc) should we have reached the end of the current level of Folders, we reset the level Column for output, and make the new Current Folders in Folder level Count equel to the next one, as we go ion now to Folders from the next level.
If CurrentLvlCnt = 0 Then
clmLvl = clmLvl + 1 'Set column position 1 to the left "down" the Folder Level Chain.
Let CurrentLvlCnt = NxtLvlCnt 'So the current Folder Level count of Folders becomes that last counted.
NxtLvlCnt = 0 'Next level of Folders currently are not in the Queue. This will be re counted for the next Folders as Sub Folders are added to the back of the Queue
Else
End If
Loop 'queue.Count > 0 main loop for all Folders=====================================================================
Application.ScreenUpdating = True
MsgBox "All Excel Files processed", vbInformation
ws.Columns("A:H").AutoFit
Exit Sub 'Normal End for no Erriors
Rem 6) 'Error handler section just put here for convenience
ErrHdlr: 'Hopefully we know why we are here, and after informing can continue ( to next file )
MsgBox prompt:="Error " & Err.Description & " with File " & oFile & ""
On Error GoTo -1 'This needs to be done to reset the VBA exceptional error state of being. Otherwise VBA "thinks"" Errors are being handeled and will not respond again to the Error handler.
On Error GoTo 0 ' Swiches off the current error handler. I do not really need to do this. But it is good practice so the error handler is only in place at the point where i next am expecting an error
GoTo NxtoFile
End Sub
Bookmarks