16

In VBA, how do I get a list of all the files with a specific extension in a specific directory?

i am unable to do Application.FileSearch, because i am using excel 2007

RubberDuck
  • 11,933
  • 4
  • 50
  • 95
Alex Gordon
  • 57,446
  • 287
  • 670
  • 1,062

4 Answers4

17

In response to your comment "so how many times do i know to run it?", this example runs until it lists all the files whose names match strPattern. Change the strFolder constant.

Public Sub ListESY()
Const strFolder As String = "C:\SomeFolder\"
Const strPattern As String = "*.ESY"
Dim strFile As String
strFile = Dir(strFolder & strPattern, vbNormal)
Do While Len(strFile) > 0
    Debug.Print strFile '<- view this in Immediate window; Ctrl+g will take you there
    strFile = Dir
Loop
End Sub
HansUp
  • 95,961
  • 11
  • 77
  • 135
  • for those curious what `Debug.Print` does, see this: http://stackoverflow.com/questions/2916287/where-does-vba-debug-print-log-to – ecoe Apr 04 '14 at 18:22
3

Dir("C:\yourPath\*.ESY", vbNormal) Returns the first file with esy extension. Each subsequent call to Dir() returns the next.

mohnston
  • 737
  • 1
  • 6
  • 18
2

The following code runs about 19 times faster than using FileSystemObject. On my machine, finding 4000 files in three different drectories took 1.57 seconds using FileSystemObject, but only 0.08 seconds using this code.

   Public Function CountFilesWithGivenExtension( _
          i_strFolderWithTerminalBackslant As String, _
          i_strExtensionIncludingPeriod As String _
          ) As Long

       If Len(Dir$(i_strFolderWithTerminalBackslant & "*" _
             & i_strExtensionIncludingPeriod)) > 0 Then

          CountFilesWithGivenExtension = 1

          While Len(Dir$) > 0

             CountFilesWithGivenExtension = _
                   CountFilesWithGivenExtension + 1

             DoEvents

          Wend
       Else
          CountFilesWithGivenExtension = 0
       End If

   End Function

Sample usage:

   Debug.Print CountFilesWithGivenExtension("C:\", ".ex*")

(The "DoEvents" is not necessary, but allows you to use Pause/Break if needed.)

Rocky Scott
  • 456
  • 4
  • 13
2

Alternative option: use the "Microsoft Scripting Runtime" library (check it in Tools...References) for the FileSystemObject family of objects. Something like the following, perhaps:

Public Function ESYFileCount(dir_path as String) as Long

Dim fil As File

    With New FileSystemObject
        With .GetFolder(dir_path)
            For Each fil In .Files
                If LCase(Right(fil.Name, 4)) = ".esy" Then
                    ESYFileCount = ESYFileCount + 1
                End If
            Next
        End With        
    End With

End Function
Mike Woodhouse
  • 51,832
  • 12
  • 88
  • 127
  • 1
    This code would be better (and earn a +1 from me) if it used late binding instead of requiring a reference to the FSO. – David-W-Fenton Jun 12 '10 at 00:37
  • @David-W-Fenton - I don't understand why late binding would be better, care to elucidate? – Mike Woodhouse Jun 12 '10 at 13:57
  • 3
    Late binding is better because of the fact that automation of the FSO can be blocked by domain policies. Late binding is *always* better for any component that is not part of the default Access set of references (with very few exceptions). The performance hit is easily avoided by caching a reference to it, and using that instead of re-initializing it each time you use it. – David-W-Fenton Jun 12 '10 at 20:15
  • 1
    From Microsoft: Use early-bound objects whenever possible, because they allow the compiler to make important optimizations. Early-bound objects are significantly faster than late-bound and make code easier to read and maintain by stating exactly what kind of objects are being used. Another advantage to early binding is that it enables useful features such as automatic code completion and Dynamic Help. Early binding reduces the number and severity of run-time errors because it allows the compiler to report errors when a program is compiled. – PBD10017 Aug 29 '13 at 02:02
  • Late to the game on this, but late binding also has advantages in applications that would be distributed across systems with varying standards and versions. – Ryan B. Nov 14 '17 at 20:29
  • Later, but my two cents is that @David-W-Fenton point sometimes is vital; I hit domain policies wall more than once, so, late-binding sometimes is the only way... anyway, I always develop with early-binding to get the Intellisense. – Marcelo Scofano Diniz Dec 13 '19 at 00:18
  • And, for that, compile time directives are essential – Marcelo Scofano Diniz Feb 01 '20 at 13:16