【问题标题】:Preserve Dir list in VBA在 VBA 中保留目录列表
【发布时间】:2014-04-08 20:29:00
【问题描述】:

如何避免重置 Dir?

d = Dir(root & "*", vbDirectory)
d = Dir(): d = Dir() ' skip . and ..
While d <> ""
    f = Dir(root & d & "\*.txt")
    While f <> ""
        ' do something with f
        f = Dir()
    Wend
    d = Dir()  ' RunTime Error "5": Invalid Procedure or Call to Argument
Wend

我的理解是当Dir(root &amp; d &amp; "\*.txt")被调用时,Dir(root &amp; "*", vbDirectory)生成的第一个列表被重置。我怎样才能避免这种情况?我尝试将第二个循环放在一个函数中

d = Dir(root & "*", vbDirectory)
d = Dir(): d = Dir() ' skip . and ..
While d <> ""
    f = Dir(root & d & "\*.txt")
    call foo(root & d)
    d = Dir()  ' RunTime Error "5": Invalid Procedure or Call to Argument
Wend

希望内部 Dir 调用超出范围,但会引发相同的错误。

有什么方法可以安全地使用Dir 循环,而不必担心在该循环中调用的函数也可能调用Dir 并破坏列表?

注意:

我知道“Scripting.FileSystemObject”,但如果可能的话想避免它。

【问题讨论】:

  • 纯粹出于好奇-我意识到这与您的问题无关-为什么厌恶FileSystemObject?在过去十年中,几乎所有可以运行 VBA 的东西都有必要的库。
  • A) 在同事之间分发代码,无需他们手动链接 Excel 中的脚本运行时。我知道 CreateObject 可以避免它,但完全避免它似乎更好。 B) 性能不可靠。如果我在文件夹或文件对象上过于频繁地调用 .Name,就会出现代码中断。我怀疑是因为它正在通过网络探测文件夹的名称,而不是在本地存储它。我不得不像蒂姆所说的那样缓存.SubFolders,而不是在每个文件中使用它。我知道它更健壮但简单的字符串更值得信赖。
  • 有道理。感谢您的观点。

标签: vba scope dir


【解决方案1】:

使用集合来缓存第一个 Dir() 循环的结果:然后在每个项目上运行第二个循环:

Sub Traverse()

    Dim col As New Collection, fpath, f, d, root

    root = "C:\_stuff\test\"

    d = Dir(root, vbDirectory)
    Do While d <> ""
        If (GetAttr(root & d) And vbDirectory) <> 0 Then
            If d <> "." And d <> ".." Then col.Add root & d
        End If
        d = Dir()
    Loop

    For Each fpath In col
        f = Dir(fpath & "\*.txt")
        While f <> ""
            'do something with f
            f = Dir()
        Wend
    Next


End Sub

【讨论】:

  • 很抱歉在选择这个之前稍等片刻,但我真的希望这不是唯一的解决方案,因为听起来我应该定义自己的 subFolders 函数。
  • 如果你想那样做,那就那样做;-) 你需要做的就是把那部分代码分解成一个单独的函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-04
  • 2015-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多