使用VBA循环文件夹中的文件?

tyr*_*rex 224 excel vba excel-2010

我想在Excel 2010中使用循环遍历目录的文件.

在循环中,我将需要

  • 文件名,和
  • 文件格式化的日期.

我编写了以下代码,如果该文件夹没有超过50个文件,则工作正常,否则它是非常慢的(我需要它与> 10000文件的文件夹一起使用).这段代码唯一的问题是查找操作file.name需要花费很多时间.

代码有效,但waaaaaay太慢(每100个文件15秒):


Sub LoopThroughFiles()
   Dim MyObj As Object, MySource As Object, file As Variant
   Set MySource = MyObj.GetFolder("c:\testfolder\")
   For Each file In MySource.Files
      If InStr(file.name, "test") > 0 Then
         MsgBox "found"
         Exit Sub
      End If
   Next file
End Sub
Run Code Online (Sandbox Code Playgroud)

问题解决了:

  1. 我的问题已通过以下解决方案Dir以特定方式(15000个文件为20秒)和使用该命令检查时间戳来解决FileDateTime.
  2. 考虑到下面的另一个答案,20秒减少到不到1秒.

bre*_*tdj 242

Dir采用外卡,因此您可以在预先添加过滤器test并避免测试每个文件时发挥重大作用

Sub LoopThroughFiles()
    Dim StrFile As String
    StrFile = Dir("c:\testfolder\*test*")
    Do While Len(StrFile) > 0
        Debug.Print StrFile
        StrFile = Dir
    Loop
End Sub
Run Code Online (Sandbox Code Playgroud)

  • 大.这只是将运行时间从20秒提高到<1秒.这是一个很大的改进,因为代码将经常运行.谢谢!! (28认同)
  • 我不认为这个改进水平(20 - xxx次) - 我认为它的通配符有所作为. (6认同)
  • @hamish,您可以更改其参数以返回不同类型的文件(隐藏文件、系统文件等) - 请参阅 MS 文档:https://learn.microsoft.com/en-us/office/vba/language/reference/user -界面帮助/目录功能 (2认同)
  • 我不明白 `StrFile = Dir` 这行代码。这对我不起作用。我用“Output = StrFile”代替。 (2认同)
  • 对于那些遇到 Kar.ma 评论并想知道同样事情的人,While 循环中的 `StrFile = Dir` 只是将 StrFile 设置为先前设置的 `Dir("c:\testfolder\* test*"`。举个例子:如果有一个 test1.xlsx 和一个 test2.xlsx,`Debug.Print StrFile` 将首先给出 test1,然后 `StrFile = Dir` 将找到下一个匹配项,即 test2 (所以留在 while 循环中)。希望能把事情弄清楚一点。 (2认同)

gra*_*tnz 155

迪尔似乎很快.

Sub LoopThroughFiles()
    Dim MyObj As Object, MySource As Object, file As Variant
   file = Dir("c:\testfolder\")
   While (file <> "")
      If InStr(file, "test") > 0 Then
         MsgBox "found " & file
         Exit Sub
      End If
     file = Dir
  Wend
End Sub
Run Code Online (Sandbox Code Playgroud)

  • 还有一个问题.如果DIR从最新文件开始循环,我可以严重提高速度.你有没有办法做到这一点? (4认同)
  • 太好了,非常感谢你.我确实使用Dir,但我不知道你也可以这样使用它.除了命令`FileDateTime`,我的问题也解决了. (3认同)
  • 我的后一个问题已经通过以下来自brettdj的评论得到了解决. (3认同)

小智 39

这是我作为函数的解释:

'#######################################################################
'# LoopThroughFiles
'# Function to Loop through files in current directory and return filenames
'# Usage: LoopThroughFiles ActiveWorkbook.Path, "txt" 'inputDirectoryToScanForFile
'# https://stackoverflow.com/questions/10380312/loop-through-files-in-a-folder-using-vba
'#######################################################################
Function LoopThroughFiles(inputDirectoryToScanForFile, filenameCriteria) As String

    Dim StrFile As String
    'Debug.Print "in LoopThroughFiles. inputDirectoryToScanForFile: ", inputDirectoryToScanForFile

    StrFile = Dir(inputDirectoryToScanForFile & "\*" & filenameCriteria)
    Do While Len(StrFile) > 0
        Debug.Print StrFile
        StrFile = Dir

    Loop

End Function
Run Code Online (Sandbox Code Playgroud)

  • 为什么功能,什么都没有回来?与brettdj给出的答案不同,除非它包含在函数中 (18认同)

Lim*_*awk 25

Dir函数是要走的路,但问题是你不能Dir这里所说的那样递归地使用函数.

我处理这个的方法是使用该Dir函数获取目标文件夹的所有子文件夹并将它们加载到一个数组中,然后将该数组传递给一个recurses函数.

这是我写的一个完成此任务的课程,它包括搜索过滤器的功能.(你必须原谅匈牙利乐谱,这是在它风靡一时的时候写的.)

Private m_asFilters() As String
Private m_asFiles As Variant
Private m_lNext As Long
Private m_lMax As Long

Public Function GetFileList(ByVal ParentDir As String, Optional ByVal sSearch As String, Optional ByVal Deep As Boolean = True) As Variant
    m_lNext = 0
    m_lMax = 0

    ReDim m_asFiles(0)
    If Len(sSearch) Then
        m_asFilters() = Split(sSearch, "|")
    Else
        ReDim m_asFilters(0)
    End If

    If Deep Then
        Call RecursiveAddFiles(ParentDir)
    Else
        Call AddFiles(ParentDir)
    End If

    If m_lNext Then
        ReDim Preserve m_asFiles(m_lNext - 1)
        GetFileList = m_asFiles
    End If

End Function

Private Sub RecursiveAddFiles(ByVal ParentDir As String)
    Dim asDirs() As String
    Dim l As Long
    On Error GoTo ErrRecursiveAddFiles
    'Add the files in 'this' directory!


    Call AddFiles(ParentDir)

    ReDim asDirs(-1 To -1)
    asDirs = GetDirList(ParentDir)
    For l = 0 To UBound(asDirs)
        Call RecursiveAddFiles(asDirs(l))
    Next l
    On Error GoTo 0
Exit Sub
ErrRecursiveAddFiles:
End Sub
Private Function GetDirList(ByVal ParentDir As String) As String()
    Dim sDir As String
    Dim asRet() As String
    Dim l As Long
    Dim lMax As Long

    If Right(ParentDir, 1) <> "\" Then
        ParentDir = ParentDir & "\"
    End If
    sDir = Dir(ParentDir, vbDirectory Or vbHidden Or vbSystem)
    Do While Len(sDir)
        If GetAttr(ParentDir & sDir) And vbDirectory Then
            If Not (sDir = "." Or sDir = "..") Then
                If l >= lMax Then
                    lMax = lMax + 10
                    ReDim Preserve asRet(lMax)
                End If
                asRet(l) = ParentDir & sDir
                l = l + 1
            End If
        End If
        sDir = Dir
    Loop
    If l Then
        ReDim Preserve asRet(l - 1)
        GetDirList = asRet()
    End If
End Function
Private Sub AddFiles(ByVal ParentDir As String)
    Dim sFile As String
    Dim l As Long

    If Right(ParentDir, 1) <> "\" Then
        ParentDir = ParentDir & "\"
    End If

    For l = 0 To UBound(m_asFilters)
        sFile = Dir(ParentDir & "\" & m_asFilters(l), vbArchive Or vbHidden Or vbNormal Or vbReadOnly Or vbSystem)
        Do While Len(sFile)
            If Not (sFile = "." Or sFile = "..") Then
                If m_lNext >= m_lMax Then
                    m_lMax = m_lMax + 100
                    ReDim Preserve m_asFiles(m_lMax)
                End If
                m_asFiles(m_lNext) = ParentDir & sFile
                m_lNext = m_lNext + 1
            End If
            sFile = Dir
        Loop
    Next l
End Sub
Run Code Online (Sandbox Code Playgroud)


小智 6

Dir 当我处理和处理其他文件夹中的文件时,该功能很容易失去焦点。

使用该组件我得到了更好的结果FileSystemObject

完整示例如下:

http://www.xl-central.com/list-files-fso.html

不要忘记在Visual Basic编辑器中设置对Microsoft Scripting Runtime的引用(通过使用“工具”>“引用”)

试试看!