I need to find all the .dwg files in all the folders below a given root folder, regardless of how deep the structure goes and how many branches there are. I guess I can figure out how to do it my repeated use of Dir function to find and search subdirectories, but I'm hoping there's a less tedious way. Something like the old dos "dir c:\cad\*.dwg /s " function. Can anyone help? Thanks . . .
[...] I guess I can figure out how to do it my repeated use of Dir Not trivially, you would have to implement a stack (using an array or Collection) to save all directories encountered and then process them in turn, because Dir() is not reentrant (it maintains global data that is overwritten during recursive invocations). Your best bet are the FindFirstFile/FindNextFile Win32 API calls. Here's some code I dug out from way back. Just call the FindFiles() sub with the root folder in which you want to start searching and the file mask you're looking for. e.g. FindFiles "C:\Program Files", "*.dwg" will find all drawings under the "C:\Program Files" directory. HTH, Uwe W. Radu www.codefancy.com ---------------------------------------------------------------------------- ----- Private Const INVALID_HANDLE_VALUE = -1 Private Const FILE_ATTRIBUTE_DIRECTORY = &H10 Private Const MAX_PATH = 260 Private Type FILETIME dwLowDateTime As Long dwHighDateTime As Long End Type Private Type WIN32_FIND_DATA dwFileAttributes As Long ftCreationTime As FILETIME ftLastAccessTime As FILETIME ftLastWriteTime As FILETIME nFileSizeHigh As Long nFileSizeLow As Long dwReserved0 As Long dwReserved1 As Long cFileName As String * MAX_PATH cAlternate As String * 14 End Type Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileA" (ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long Private Sub FindFiles(ByVal Folder As String, ByVal Mask As String) Dim hFind As Long Dim FindData As WIN32_FIND_DATA Dim Filename As String ' find all matching files in this folder hFind = FindFirstFile(Folder & "\" & Mask, FindData) If hFind <> INVALID_HANDLE_VALUE Then Do ' if not a folder, it's a file we're interested in If (FindData.dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY) = 0 Then Filename = Left(FindData.cFileName, InStr(1, FindData.cFileName, vbNullChar) - 1) ProcessFile Folder & "\" & Filename End If Loop Until FindNextFile(hFind, FindData) = 0 End If FindClose hFind ' now recurse into all subfolders hFind = FindFirstFile(Folder & "\*", FindData) If hFind <> INVALID_HANDLE_VALUE Then Do ' check if a folder If (FindData.dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY) > 0 Then Filename = Left(FindData.cFileName, InStr(1, FindData.cFileName, vbNullChar) - 1) ' ignore . and .. folders If Filename <> "." And Filename <> ".." Then FindFiles Folder & "\" & Filename, Mask End If End If Loop Until FindNextFile(hFind, FindData) = 0 End If FindClose hFind End Sub Private Sub ProcessFile(ByVal Filename As String) Debug.Print Filename End Sub
i hv tried using Dir " .." as well as fileSystemObject, with recursion. i hv not found simple built in features, though it can be done in VBA using mso(microsoft office) features. if u need such recursion method, let me know.
This solution sounds bit 'native' way - but quite easy and simple! execute "dir c:\cad\*.dwg /s /b > c:\output.txt" (i had added "/b > c:\output.txt" to your example) This creates a ASCII file containing the full path of the DWG files. You can read them one line by line and load it into array or list box or to any other thing. Dont forget to close the file! - Narayanan
Tony, The code below was posted in this group a couple years ago by John Wilde. I use it all the time. It's not the fastest solution but it works. Gary Option Explicit Public Sub FilesAllDirs(sStartPath As String, vFileList As Variant) 'Modified from code supplied by John Wilde, AutoDesk VBA Customization Newsgroup Dim sCurrPath As String Dim iNumFiles As Integer Dim iNumDirs As Integer Dim sNameTemp As String Dim sLastPath As String Dim iDirCount As Integer Dim iLoopCount As Integer 'Assign the sCurrPath variable.Check for and add trailing back slash if required If Right(sStartPath, 1) <> "\" Then sCurrPath = sStartPath & "\" Else sCurrPath = sStartPath sLastPath = sCurrPath 'Find the number of directories in sCurrPath iLoopCount = 0 sNameTemp = Dir(sCurrPath, vbDirectory) Do While sNameTemp <> "" If sNameTemp <> "." And sNameTemp <> ".." Then If (GetAttr(sCurrPath & sNameTemp) And vbDirectory) = vbDirectory Then iLoopCount = iLoopCount + 1 End If End If sNameTemp = Dir Loop iNumDirs = iLoopCount If iNumDirs > 0 Then ReDim aDirList(0 To iNumDirs - 1) As String iLoopCount = 0 'Populate the aDirList array with the names of directories in sCurrPath sNameTemp = Dir(sCurrPath, vbDirectory) 'Retrieve the first entry. Do While sNameTemp <> "" 'Start the loop. If sNameTemp <> "." And sNameTemp <> ".." Then 'Use bitwise comparison to make sure sNameTemp is a directory. If (GetAttr(sCurrPath & sNameTemp) And vbDirectory) = vbDirectory Then aDirList(iLoopCount) = sCurrPath & sNameTemp 'Store entry only if it represents a directory. iLoopCount = iLoopCount + 1 End If End If sNameTemp = Dir ' Get next entry. Loop End If 'Find the number of DWG files in sCurrPath iNumFiles = 0 iLoopCount = 0 sNameTemp = Dir(sCurrPath + "*.dwg", vbNormal) 'Tell the Dir command what to look for Do While sNameTemp <> "" 'Counts the number of files in this directory that fit above description sNameTemp = Dir iLoopCount = iLoopCount + 1 Loop iNumFiles = iLoopCount If iNumFiles > 0 Then ReDim aFileList(0 To iNumFiles - 1) As String 'An array to store the names of the files iLoopCount = 0 'Populate the file array (vFileList)with the names of files in sCurrPath sNameTemp = Dir(sCurrPath + "*.dwg", vbNormal) ' Retrieve the first entry. Do While sNameTemp <> "" 'Start the loop. aFileList(iLoopCount) = sCurrPath & sNameTemp ReDim Preserve vFileList(UBound(vFileList) + 1) vFileList(UBound(vFileList)) = sCurrPath & sNameTemp sNameTemp = Dir 'Get next entry. iLoopCount = iLoopCount + 1 Loop End If 'Call the FilesAlldirs routine (recursively) for each subdirectory in sCurrPath. The base case (when 'the function returns to the routine that called it) is when the For loop is finished For iDirCount = 0 To iNumDirs - 1 FilesAllDirs (aDirList(iDirCount)), vFileList Next iDirCount sCurrPath = sLastPath Exit Sub End Sub Public Sub FileSU() 'Modified from code supplied by John Wilde, AutoDesk VBA Customization Newsgroup Dim sStartPath As String Dim vFileList() As Variant Dim iLoopCount As Integer sStartPath = ThisDrawing.Path ReDim vFileList(0) 'Returns with "vFileList" containing fully qualified path of all .dwg files 'in the directory specified in "sStartPath" and all of its subordinate directories FilesAllDirs sStartPath, vFileList For iLoopCount = 0 To UBound(vFileList) Debug.Print vFileList(iLoopCount) Next iLoopCount End Sub