【问题标题】:Loop Through All Subfolders Using VBA [duplicate]使用VBA循环遍历所有子文件夹[重复]
【发布时间】:2014-05-03 22:21:18
【问题描述】:

我正在寻找一个将遍历指定文件夹的所有子文件夹的 VBA 脚本。当我说所有子文件夹时,我的意思是指定文件夹中的每个文件夹,其中的每个文件夹,以及其中的每个文件夹......理论上可能有无限的嵌套子文件夹,但实际上它可能不会超过 3或 4. 我正在使用 VBA Scripting Runtime 对象,因此一旦我循环进入文件夹,我就可以检查一些文件的属性(但我知道如何做这部分)。

感谢您的帮助!

这道题不同于前面题目中列出的“相似”题中包含已知目录的问题,而这里的需要是查找已知目录和未知目录。还需要多层子目录。你们真的应该在启动“重复”之前阅读问题。

【问题讨论】:

标签: vba filesystemobject


【解决方案1】:

只是一个简单的文件夹向下钻取。

sub sample()
    Dim FileSystem As Object
    Dim HostFolder As String

    HostFolder = "C:\"

    Set FileSystem = CreateObject("Scripting.FileSystemObject")
    DoFolder FileSystem.GetFolder(HostFolder)
end  sub

Sub DoFolder(Folder)
    Dim SubFolder
    For Each SubFolder In Folder.SubFolders
        DoFolder SubFolder
    Next
    Dim File
    For Each File In Folder.Files
        ' Operate on each file
    Next
End Sub

【讨论】:

  • 谢谢,我觉得这很简单!
  • 没问题,所有程序员都会时不时地保留这个子文件夹迭代的副本,它主要是复制和粘贴。不要忘记标记我的朋友的答案。
  • 为了完整起见,在下面添加了非递归方法;)
  • 你忘记定义什么了吗?不适合我:(
  • 我猜你不能仅仅使用 SubFolder 作为变体。它需要 Dim SubFolder as Object
【解决方案2】:

为了补充 Rich 的递归答案,一种非递归方法。

Public Sub NonRecursiveMethod()
    Dim fso, oFolder, oSubfolder, oFile, queue As Collection

    Set fso = CreateObject("Scripting.FileSystemObject")
    Set queue = New Collection
    queue.Add fso.GetFolder("your folder path variable") 'obviously replace

    Do While queue.Count > 0
        Set oFolder = queue(1)
        queue.Remove 1 'dequeue
        '...insert any folder processing code here...
        For Each oSubfolder In oFolder.SubFolders
            queue.Add oSubfolder 'enqueue
        Next oSubfolder
        For Each oFile In oFolder.Files
            '...insert any file processing code here...
        Next oFile
    Loop

End Sub

您可以将队列用于 FIFO 行为(如上所示),或者您可以将堆栈用于 LIFO 行为,其处理顺序与递归方法相同(将 Set oFolder = queue(1) 替换为 Set oFolder = queue(queue.Count) 并替换 queue.Remove(1)使用queue.Remove(queue.Count),并可能重命名变量...)

【讨论】:

  • +1 这真是太糟糕了。我需要阅读更多关于收藏的内容。
  • @Rich 会的,但其他 2 个已存储在集合中,然后我们在接下来的 2 个循环中处理(不要忘记 queue.Remove 1 删除第一个文件夹,所以第二个文件夹是现在是集合的第一个成员,因此在下一次调用 queue(1) 时检索。堆栈方法将采用相反的方式,始终对添加的最后一个文件夹进行操作(将 queue(1) 替换为 queue(queue.Count)和 queue.Remove 1 with queue.Remove queue.Count)。
  • 集合在 VBA 中非常有用,因为它们基本上是我们唯一的“列表”类型的对象(键控字典也可以从 Scripting.Runtime 中使用)。您可以在处理某些内容时轻松使用它们添加结果,然后担心在最后进入数组(节省使用 Redim 保留每个循环的数组复制开销)。您可以使用它们来查找唯一性、映射值、对大量数据进行快速查找以及许多其他事情。
  • 我想指出的是,如果处理顺序对您很重要,则此方法不会给出与递归方法相同的顺序。这里的文件夹处理顺序是这样的:Root,Root\Sub1,Root\Sub2,Root\Sub1\Sub1.1,Root\Sub1\Sub1.2,Root\Sub2\Sub2.1,Root\Sub2\Sub2.2... 也就是逐级处理文件夹。
  • @Lapis 好点。可以通过使用堆栈而不是队列以非递归方式获得相同的顺序(因此,而不是x = queue(1): queue.remove 1,它将类似于x = queue(queue.count): queue.remove(queue.count)
猜你喜欢
  • 2017-04-06
  • 2012-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-07
相关资源
最近更新 更多