It's a long-established truism that, "you can't use VB's Dir function
recursively." Right? Wrong! You most certainly can use it within recursive
functions, but if you call a function recursively from within a Dir loop you are
asking for serious trouble. The reason for this is that Dir uses a single
hFindFile handle with a series of FindFirstFile / FindNextFile / FindClose API calls. The design is
simple and elegant, and you're stuck with its limitations.
So what can you do to drill down recursively through a folder hierarchy,
looking for all (or specific) files under a given location? Your choices come
down to writing your own version of Dir, with each recursive call starting a new
call to FindFirstFile, and storing a unique hFileFile handle. Or, using Dir smartly.
To use Dir recursively, the secret is to run two loops within each level. The
first Dir loop scans for all matching files and folders. Folders are stored in
one array, files in another. When that initial loop is completed, run another
loop passing each element of the Folders array to this same function. Simple
concept, horribly botched time and time again.
The sample you can download from this page takes the concept a step farther,
and encapsulates a recursive, multi-filespec search into an event-raising class
module. Drop this into a project, and you can use it as simply as this:
Private WithEvents dd As CDirDrill
Private Sub Command1_Click()
dd.Folder = CurDir$
dd.Pattern = "*.bas;*.cls;*.frm;*.ctl"
dd.BeginSearch
End Sub
Private Sub dd_Done(ByVal TotalFiles As Long, ByVal TotalFolders As Long)
Debug.Print "Found "; TotalFiles; " files in "; TotalFolders; " folders."
End Sub
Private Sub dd_NewFile(ByVal FileSpec As String, Cancel As Boolean)
' Show that we found one...
Debug.Print Space$(5) & dd.ExtractName(FileSpec)
' Do any other processing here...
End Sub
Private Sub dd_NewFolder(ByVal FolderSpec As String, Cancel As Boolean)
Debug.Print FolderSpec
End Sub
Too easy? I think so.
Oh, this sample also includes a bonus module that recreates several of
the new-to-VB6 string functions, so you can use them in VB5 as well. If you've
become used to Join, Split, InstrRev, Replace, and/or Reverse in VB6, now you
can use them in VB5 too! These functions were "originally stolen" from
freevbcode.com,
and have been heavily modified over the years. If this topic interests you,
you'll probably really like the vbspeed
site, for it's intensively anal optimizations of these and many other functions.