小弟写了一个简单的函数,显示一个目录下所有的目录和文件
不知为何如果目录结构出现3层则出现问题,请教高手
小弟的调用方式为:ShowFolderAndFiles "C:\test\"
test目录就一个目录
////////////////////////////////////////////////////////////////////////
'显示一个目录下所有的文件,如果是目录的话,则继续调用这个函数
Public Sub ShowFolderAndFiles(FolderPath As String)
'   判断是否为目录,如果不是目录则不处理
    If Dir(FolderPath, vbDirectory) = "" Then Exit Sub
'   如果为目录则打印处理目录
    Debug.Print FolderPath
    
    Dim CurFolder As String
    Dim FolderName As String
    FolderName = Dir(FolderPath, vbDirectory)
    While (FolderName <> "")
        If FolderName <> "." And FolderName <> ".." Then
            If (GetAttr(FolderPath & FolderName) And vbDirectory) = vbDirectory Then
                If CurFolder = "" Then
                    CurFolder = FolderPath & FolderName & "\"
                Else
                    CurFolder = CurFolder & FolderName & "\"
                End If
                '如果是子目录则调用本身继续操作
                ShowFolderAndFiles CurFolder
            Else
                '如果是文件则打印出文件的名称
                Debug.Print FolderName
            End If
        End If
        FolderName = Dir
    Wend
End Sub

解决方案 »

  1.   

    是不是这一行有问题:
    FolderName = Dir
      

  2.   

    我不是高手,不知道这里该怎么办,当时我觉得,可能是递归调用返回之前,dir就在遍历另一个文件加了,返回的时候,dir还是会继续遍历那个文件加,就会出问题
      

  3.   

    是错误的,当进行到递归的语句 ShowFolderAndFiles CurFolder 时,Dir的路径已经改变了,当递归完毕以后,再执行前一个目录的 FolderName = Dir 时,当然会发生错误啦。
      

  4.   

    应该这样做:在某一层使用Dir的时候,即使找到了子目录,也不应该立即递归,而是加入一个集合里面。等这一层Dir完以后,在循环一次集合。
      

  5.   

    FolderName = Dir(FolderPath & "..\", vbDirectory)
    我在每一个递归调用返回的地方加一句这个,就可以返回到原来的目录中,但是这时又会重复遍历已经遍历的文件夹,而且文件夹的名字还会出错,这个不知道怎么改才好
      

  6.   

    不是说了吗??应该这样做:在某一层使用Dir的时候,即使找到了子目录,也不应该立即递归,而是加入一个集合里面。等这一层Dir完以后,在循环一次集合。
      
      

  7.   

    真是没办法,只有把修改后的代码贴上了:
    Public Sub ShowFolderAndFiles(FolderPath As String)
    '   判断是否为目录,如果不是目录则不处理
        If Dir(FolderPath, vbDirectory) = "" Then Exit Sub
    '   如果为目录则打印处理目录
        List1.AddItem FolderPath
            
        Dim CurFolder As String
        Dim FolderName As String
        Dim sFile As Collection
        Dim i As Long
        Set sFile = New Collection
        FolderName = Dir(FolderPath, vbDirectory)
        While (FolderName <> "")
            If FolderName <> "." And FolderName <> ".." Then
                If (GetAttr(FolderPath & FolderName) And vbDirectory) = vbDirectory Then
                    If CurFolder = "" Then
                        CurFolder = FolderPath & FolderName & "\"
                    Else
                        CurFolder = CurFolder & FolderName & "\"
                    End If
                    '如果是子目录则加入集合
                    sFile.Add CurFolder
                Else
                    '如果是文件则打印出文件的名称
                    List1.AddItem FolderName
                End If
            End If
            FolderName = Dir
        Wend
        If sFile.Count > 0 Then
            For i = 1 To sFile.Count
                ShowFolderAndFiles sFile.Item(i)
            Next
        End If
        Set sFile = Nothing
    End Sub
      

  8.   

    Dir 会返回匹配 pathname 的第一个文件名。若想得到其它匹配 pathname 的文件名,再一次调用 Dir,且不要使用参数。如果已没有合乎条件的文件,则 Dir 会返回一个零长度字符串 ("")。一旦返回值为零长度字符串,并要再次调用 Dir 时,就必须指定 pathname,否则会产生错误。不必访问到所有匹配当前 pathname 的文件名,就可以改变到一个新的 pathname 上。但是,@@@@不能以递归方式来调用 Dir 函数@@@@@@@@@。以 vbDirectory 属性来调用 Dir 不能连续地返回子目录。
      

  9.   

    把上面代码的 List1.AddItem 改为 Debug.Print
      

  10.   


    Public Sub BianLi(ByVal Path$, ByRef cTemp As Collection)
        Dim fso, objFolder, objSubFolders, objFile, objSubFolder, sMax As Long, nowPathName$, nowPath$
        Set fso = CreateObject("scripting.filesystemobject")
        If Right(Path, 1) <> "\" Then Path = Path & "\"
        Set objFolder = fso.GetFolder(Path)
        Set objFiles = objFolder.Files
        For Each objFile In objFiles
            DoEvents
            sMax = cTemp.Count + 1
            nowPathName = CStr(Path) & objFile.Name
            nowPathName = nowPathName & "||" & FileLen(nowPathName)
            cTemp.Add nowPathName, CStr(sMax)
        Next
        Set objSubFolders = objFolder.Subfolders
        For Each objSubFolder In objSubFolders
            DoEvents
            nowPath = Path & objSubFolder.Name
            If Right(nowPath, 1) <> "\" Then nowPath = nowPath & "\"
            BianLi nowPath, cTemp
        Next
        Set objFolder = Nothing
        Set objSubFolders = Nothing
        Set fso = Nothing
    End Sub我想上面的代码,对你有用!~
      

  11.   

    现在决定了,给“lc_mtt(柠檬)”和“arrowcy(长弓手)”各10分,谢谢诸位的帮助,下面是我的完成后的代码:'显示一个目录下所有的文件,如果是目录的话,则继续调用这个函数
    Public Sub ShowFolderAndFiles(FolderPath As String)
    '   判断是否为目录,如果不是目录则不处理
        If Dir(FolderPath, vbDirectory) = "" Then Exit Sub
        Dim FolderNameList As New Collection
    '   如果为目录则打印处理目录
        Print #1, Mid(FolderPath, 56, 60)
        Dim CurFolder As String
        Dim FolderName As String
        FolderName = Dir(FolderPath, vbDirectory)
        While (FolderName <> "")
            If FolderName <> "." And FolderName <> ".." Then
                If (GetAttr(FolderPath & FolderName) And vbDirectory) = vbDirectory Then
                        CurFolder = FolderPath & FolderName & "\"
                    '如果是子目录则调用本身继续操作
                    FolderNameList.Add CurFolder
                Else
                    '如果是文件则打印出文件的名称
                    If Right(FolderName, 4) = "java" Then Print #1, Tab(10); FolderName
                End If
            End If
            FolderName = Dir
        Wend
        Dim i As Integer
        For i = 1 To FolderNameList.Count
            ShowFolderAndFiles FolderNameList(i)
        Next i
        Set FolderNameList = Nothing
    End Sub