This is an addition to the answer of 1 Oct 2017. I tried to make the recursion more self-explanatory, and in the end, it evolved to this. A nice example how something can become complicated.
Option Compare Database
Option Explicit
'
' two variables at module level in order to exit the recursion if needed
'
Dim ProductFolderIsFound As Boolean ' keep track if product-folder is found
Dim TheFoundProductFolder As String ' return the full-path if product-folder is found
Dim FolderCounter As Long ' trying to keep track of the recursion
'
' check for multiple occurrences, switch the comment before the line with 'true' and 'false'
'
Const StopWhenFound As Boolean = False ' yes or no
'Const StopWhenFound As Boolean = True ' yes or no
Const UncPathDivider As String = ";" & vbCrLf ' if found, separate them by this string
'##################'
Public Sub MyFind()
'
' basis for this module coming from this URL :
' https://stackoverflow.com/questions/22645347/loop-through-all-subfolders-using-vba
'
Dim FileSystem As Object ' will become 'Scripting.FileSystemObject'
Dim HostFolder As String ' base-location for the search
Dim ProductToSearchFor As String
'----------------
' Initialisation
'----------------
HostFolder = "B:\" ' "Z:\path\to\search"
'ProductToSearchFor = "1234"
'ProductToSearchFor = "Product 7"
'ProductToSearchFor = "Category 2"
ProductToSearchFor = "Product 1"
FolderCounter = 1
' parameters for the recursion
ProductFolderIsFound = False ' in the start, productfolder is not yet found ;-)
TheFoundProductFolder = "" ' in the start, productfolder is not yet found ;-)
'-------------------
' get the work done
'-------------------
' debug message
Debug.Print "' ==>> searching for : '" & ProductToSearchFor & _
"' , starting in location : '" & HostFolder & "' <<=="
' give FileSystem his necessary type, in order to call the function '.GetFolder'
' ==>> debug.print VarType(FileSystem) will still return '9', like type 'Object'
Set FileSystem = CreateObject("Scripting.FileSystemObject")
' start of recursion, by passing the base location as a 'Scripting.FileSystemObject'
DoFolder FileSystem.GetFolder(HostFolder), ProductToSearchFor, FolderCounter, ""
'--------
' result
'--------
'
' What to do when yes or no the product-folder is found
'
If ProductFolderIsFound Then
Debug.Print "' ==>> Found : " & vbCrLf & TheFoundProductFolder & "' <<=="
Else
Debug.Print "' ==>> NOT found : '" & ProductToSearchFor & _
"' in location : '" & HostFolder & "' <<=="
End If
End Sub
'###################'
Private Sub DoFolder(ByVal Folder As Object, _
ByVal ProductToSearchFor As String, _
ByVal FolderID As Long, _
ByVal PreviousFolderIDs As String) ' important : ByVal instead of ByRef
'
' the parameter 'Folder' [will be/needs to be] compatable type 'Scripting.FileSystemObject'
' because we use the function '.GetFolders' and the property '.Name'
'
Dim SubFolder As Object
Dim MessageLine As String
'
' create a debug-message-line : "'" & Folder & (some spaces) & "//Name-Part = " & Folder.Name
' remember, 'Folder' returns the full path and 'Folder.Name' only the last part of the full path
'
MessageLine = "'" & PreviousFolderIDs & "__" & FolderID & ""
If Len(MessageLine) <= 15 Then
' make the message at least 50 characters, so the 'name-part' can be in a second column
MessageLine = MessageLine & Space(15 - Len(MessageLine))
End If
MessageLine = MessageLine & Folder
If Len(MessageLine) <= 60 Then
' make the message at least 50 characters, so the 'name-part' can be in a second column
MessageLine = MessageLine & Space(60 - Len(MessageLine))
End If
MessageLine = MessageLine & "//Name-Part = " & Folder.Name
Debug.Print MessageLine
'-------------
' try to find
'-------------
'
' if the 'Folder' is the desired product-folder, stop searching
' if desired switch the function 'Mid' with the 'Left'
'
'If Left(Folder.Name, Len(ProductToSearchFor)) = ProductToSearchFor Then
If InStr(Folder.Name, ProductToSearchFor) > 0 Then
Debug.Print "'" & Space(14) & "searching for : " & ProductToSearchFor & " ==>> FOUND !"
' let the rercursive stack know that the folder is found
ProductFolderIsFound = True
' return the full location of the desired product-folder
TheFoundProductFolder = TheFoundProductFolder & Folder & UncPathDivider
If ProductFolderIsFound And StopWhenFound Then
'MsgBox "Found !", vbInformation
Exit Sub
End If
End If
'---------------------------------
' recursive call for this funtion
'---------------------------------
'
' if product-folder not yet found, check all the subfolders of the current 'Folder'
'
For Each SubFolder In Folder.SubFolders
FolderCounter = FolderCounter + 1
DoFolder SubFolder, ProductToSearchFor, FolderCounter, PreviousFolderIDs & FolderID & ";"
' if product-folder has been found, no need to scan further thru the folder-structure
If ProductFolderIsFound And StopWhenFound Then
Exit For
End If
Next
End Sub
This could give the following results in your VBA-Direct-window :
'##################################'
Private Sub VBA_Window_Direct_003()
'
'myfind
' ==>> searching for : 'Product 1' , starting in location : 'B:\' <<==
'__1 B:\ //Name-Part =
'1;__2 B:\Test Root Folder //Name-Part = Test Root Folder
'1;2;__3 B:\Test Root Folder\Category 1 //Name-Part = Category 1
'1;2;3;__4 B:\Test Root Folder\Category 1\Product 1 //Name-Part = Product 1
' searching for : Product 1 ==>> FOUND !
'1;2;3;__5 B:\Test Root Folder\Category 1\Product 2 //Name-Part = Product 2
'1;2;3;__6 B:\Test Root Folder\Category 1\Product 3 //Name-Part = Product 3
'1;2;__7 B:\Test Root Folder\Category 2 //Name-Part = Category 2
'1;2;7;__8 B:\Test Root Folder\Category 2\Product 6 //Name-Part = Product 6
'1;2;7;__9 B:\Test Root Folder\Category 2\Product 7 //Name-Part = Product 7
'1;2;__10 B:\Test Root Folder\Category 3 //Name-Part = Category 3
'1;2;__11 B:\Test Root Folder\Category 4 //Name-Part = Category 4
'1;2;11;__12 B:\Test Root Folder\Category 4\Product 12 //Name-Part = Product 12
' searching for : Product 1 ==>> FOUND !
' ==>> Found :
B:\Test Root Folder\Category 1\Product 1;
B:\Test Root Folder\Category 4\Product 12;
' <<==
End Sub
In the first column, the numbers are an abbreviation for the different subfolders: 1=B:
, 2=Test Root Folder
, 3=Category 1
and so on.