Results 1 to 8 of 8

Thread: Anyone got a good function to loop through all Sub Folders and Files?

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2001
    Location
    London UK
    Posts
    671

    Anyone got a good function to loop through all Sub Folders and Files?

    Sorry I am feeling lazy today, but I am sure it must be a fairly common thing to want to do so hopefully someone out there has some code that will do this?


  2. #2
    Addicted Member
    Join Date
    Mar 2001
    Posts
    130
    It's slow, but it works.
    Code:
    Option Explicit
    
    Dim mlFileNum As Long
    Dim msFile() As String
    
    Sub main()
    
    ReDim msFile(1 To 100) As String
    
    Dim lX As Long
    Dim sStartPath As String
    
    sStartPath = InputBox("What is the starting folder?")
    
    FindFiles sStartPath
    
    For lX = 1 To mlFileNum
        Debug.Print msFile(lX)
    Next lX
    
    Debug.Print mlFileNum & " files found."
    Debug.Print
    
    End Sub
    
    
    Sub FindFiles(ByVal sPath As String)
    
    Dim sNext As String
    Dim sDir() As String
    Dim lDirNum As Long
    Dim lX As Long
    
    ReDim sDir(1 To 50) As String
    
    lDirNum = 0
    
    If Right(sPath, 1) <> "\" Then sPath = sPath + "\"
    
    sNext = Dir(sPath, vbDirectory)
        
    Do
        Do While Left(sNext, 1) = "."
            sNext = Dir
        Loop
        
        If sNext = "" Then Exit Do
        
        If (GetAttr(sPath + sNext) And vbDirectory) = vbDirectory Then
            
            If lDirNum Mod 50 = 0 Then
                ReDim Preserve sDir(1 To lDirNum + 50) As String
            End If
                
            lDirNum = lDirNum + 1
            sDir(lDirNum) = sPath + sNext
        Else
            
            If mlFileNum Mod 100 = 0 Then
                ReDim Preserve msFile(1 To mlFileNum + 100) As String
            End If
            
            mlFileNum = mlFileNum + 1
            msFile(mlFileNum) = sPath + sNext
        End If
        
        sNext = Dir
    Loop
    
    For lX = 1 To lDirNum
        FindFiles (sDir(lX))
    Next lX
    
    End Sub
    -mort

  3. #3
    Registered User Nucleus's Avatar
    Join Date
    Apr 2001
    Location
    So that's what you are up to ;)
    Posts
    2,530

    Here is some code

    In a module

    VB Code:
    1. Option Explicit
    2.  
    3. Private Const MAX_PATH = 260
    4. Private Const FILE_ATTRIBUTE_DIRECTORY = &H10
    5.  
    6. Public Type FILETIME
    7.         dwLowDateTime As Long
    8.         dwHighDateTime As Long
    9. End Type
    10.  
    11. Public Type WIN32_FIND_DATA
    12.         dwFileAttributes As Long
    13.         ftCreationTime As FILETIME
    14.         ftLastAccessTime As FILETIME
    15.         ftLastWriteTime As FILETIME
    16.         nFileSizeHigh As Long
    17.         nFileSizeLow As Long
    18.         dwReserved0 As Long
    19.         dwReserved1 As Long
    20.         cFileName As String * MAX_PATH
    21.         cAlternate As String * 14
    22. End Type
    23.  
    24. Public Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long
    25. Public Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long
    26. Public Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileA" (ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long
    27.  
    28. Private files()          As String
    29.  
    30. Public Function EnumFiles(ByVal Path As String, Optional Subdirectories As Boolean = False) As Variant
    31.  'Nucleus
    32.  ReDim files(1 To 1)
    33.  Call EF(Path, Subdirectories)
    34.  
    35.  If Len(files(1)) Then EnumFiles = files Else EnumFiles = Null
    36.  Erase files
    37. End Function
    38.  
    39. Private Sub EF(ByVal Path As String, Optional Subdirectories As Boolean = False)
    40.  Dim hFirstFound         As Long
    41.  Dim hFound              As Long
    42.  Dim WFD                 As WIN32_FIND_DATA
    43.  Dim fname               As String
    44.  
    45.  If Right$(Path, 1) <> "\" Then Path = Path & "\"
    46.  hFirstFound = FindFirstFile(Path & "*.*", WFD)
    47.  hFound = (hFirstFound > 0)
    48.  Do While hFound
    49.     fname = Left(WFD.cFileName, InStr(1, WFD.cFileName, Chr(0)) - 1)
    50.     If fname <> "." And fname <> ".." Then
    51.    
    52.         If WFD.dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY Then
    53.            
    54.             If Subdirectories Then Call EF(Path & fname, Subdirectories)
    55.        
    56.         Else
    57.        
    58.             If Len(files(1)) Then ReDim Preserve files(1 To UBound(files) + 1)
    59.             files(UBound(files)) = Path & fname
    60.            
    61.         End If
    62.        
    63.     End If
    64.    
    65.     hFound = FindNextFile(hFirstFound, WFD)
    66.  Loop
    67.  
    68.  FindClose hFirstFound
    69. End Sub

    Usage:
    VB Code:
    1. Private Sub Command2_Click()
    2. Dim a As Variant, i As Long
    3.  
    4. a = EnumFiles("c:\tmp", True)
    5.  
    6. If Not IsNull(a) Then
    7.    For i = 1 To UBound(a)
    8.       Debug.Print a(i)
    9.    Next i
    10. Else
    11.     MsgBox "No files found in that directory matching " & _
    12.         "the extension if you passed one."
    13. End If
    14. End Sub

  4. #4

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2001
    Location
    London UK
    Posts
    671
    Thank you both very much, that was exactly what I needed.

    I'm not normally that lazy (honestly)

  5. #5
    It could be faster if you try to use the *gag* FileSystemObject.

  6. #6
    Registered User Nucleus's Avatar
    Join Date
    Apr 2001
    Location
    So that's what you are up to ;)
    Posts
    2,530
    Originally posted by filburt1
    It could be faster if you try to use the *gag* FileSystemObject.
    Are you sure it is faster when app is compiled? I haven't taken the time to compare compiled version vs fso, but it would be interesting to see a comparison.

  7. #7
    My guess is that it would be a bit faster, as MS wrote the FSO in C or C++.

  8. #8
    Registered User Nucleus's Avatar
    Join Date
    Apr 2001
    Location
    So that's what you are up to ;)
    Posts
    2,530
    As it is mostly calls directly to the API speed should be quite comparable even though FSO is in C++. Speed would also depend on the implementation, which is why I would like to see a comparison, perhaps it is possible to tweak the implementation to outdo the fso?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width