2016-04-03 35 views
0

下面是一个示例代码。它遍历给定目录的所有子目录,并在即时窗口中打印目录和文件名。问题是程序如何在本行内自行调用“TraversePath”TraversePath path & directory &“\”“? 。这是递归..那么有没有更好的方法来编码?因为除非我们在正确的上下文中使用递归,否则总会有溢出的机会。如何在不递归的情况下编写这个VBA程序

Sub TraversePath(path As String) 
    Dim currentPath As String, directory As Variant 
    Dim dirCollection As Collection 
    Set dirCollection = New Collection 

    currentPath = Dir(path, vbDirectory) 

    'Explore current directory 
    Do Until currentPath = vbNullString 
     Debug.Print currentPath 
     If Left(currentPath, 1) <> "." And _ 
      (GetAttr(path & currentPath) And vbDirectory) = vbDirectory Then 
      dirCollection.Add currentPath 
     End If 
     currentPath = Dir() 
    Loop 

    'Explore subsequent directories 
    For Each directory In dirCollection 
     Debug.Print "---SubDirectory: " & directory & "---" 
    'How program is calling/executing below line of code 
     TraversePath path & directory & "\" 
    Next directory 

End Sub 

Sub Testprogram() 

    TraversePath "D:\VBA\" 

End Sub 
+1

这是递归。它是计算机科学的标准工具。遍历树是一个常见的用例。请参阅https://en.wikipedia.org/wiki/Recursion_(computer_science) –

回答

2

您对堆栈溢出的担忧在此使用递归被放错位置。例如,

Sub PlumbDepth(ByVal n As Long) 
    Debug.Print n 
    n = n + 1 
    PlumbDepth n 
End Sub 

当我进入

PlumbDepth 1 

在立即窗口,直到我6000次递归调用做我没有得到一个不折不扣的堆栈空间的错误。对于步行文件系统,除非你有类似的东西

C:\MyDocuments\MySecretDocuments\MySecretSecretDocuments\...\MySecretSecretSecretSecret....(5000 secrets later)Documents 

你不打算堆栈。我怀疑操作系统会在它成为问题之前就反对。在这种情况下使用非递归算法的唯一正当理由是,如果由于函数调用开销,递归算法花费的时间太长。

1

一个更好的办法可能是这样的:

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

    Set fso = CreateObject("Scripting.FileSystemObject") 
    Set queue = New Collection 
    queue.Add fso.GetFolder("D:\VBA") '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 
      Debug.Print oSubfolder 
     Next oSubfolder 
     For Each oFile In oFolder.Files 
      '...insert any file processing code here... 
      Debug.Print oFile 
     Next oFile 
    Loop 

End Sub 
相关问题