Searching directory tree/subdirectories

Discussion in 'AutoCAD' started by Tony Burba, Jul 1, 2003.

  1. Tony Burba

    Tony Burba Guest

    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 . . .
     
    Tony Burba, Jul 1, 2003
    #1
  2. Tony Burba

    Mark Propst Guest

    there must be many examples of a recursive folder search on google.
     
    Mark Propst, Jul 1, 2003
    #2
  3. Tony Burba

    Uwe W. Radu Guest

    [...] 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
     
    Uwe W. Radu, Jul 1, 2003
    #3
  4. Mark Dubbelaar, Jul 1, 2003
    #4
  5. Tony Burba

    Soe Guest

    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.
     
    Soe, Jul 1, 2003
    #5
  6. Tony Burba

    Narayanan Guest

    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
     
    Narayanan, Jul 1, 2003
    #6
  7. 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
     
    Gary McMaster, Jul 1, 2003
    #7
  8. Tony Burba

    Tony Burba Guest

    Thank you all for several excellent suggestions. I'll be trying them.
     
    Tony Burba, Jul 2, 2003
    #8
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.