VBA (Excel): Iterating through files in folder via FileSystemObject

帅比萌擦擦* 提交于 2020-01-09 10:33:27

问题


Ok, so I consider myself an Excel VBA expert (even though I've not done much with it for a while) but I'm stumped on this one - that obviously means it is something extremely simple which I've overlooked due to my arrogance :D

I'm using a FileSystemObject assigned to a global variable (called "myFSO" - original, I know...) and using two other global variables - xFolder and xFile - to iterate through all the files within a folder, and perform actions on each file within the folder.

This is the code:

Global myFSO As FileSystemObject
Global xFolder As Scripting.Folder
Global xFile As Scripting.File

Public Sub GetData()

Set bgd = ThisWorkbook.Sheets("BGD")
Set myFSO = New FileSystemObject
Set xFolder = myFSO.GetFolder(bgd.Range("C4").Value)

For Each xFile In xFolder.Files
          <do stuff here>
Next xFile

End Sub

So, when I step through the code, I can see that the xFolder is being assigned correctly. If I add a Watch or insert

Debug.Print xFolder.Files.Count

into the code, it returns the correct file count, so everything seems to be setup fine to go into the For loop and do what it needs to do.

Once I step past the For Each... statement line however the code just runs to the end of the routine, completely missing out the whole of the code nested within the For Each... Next code. It doesn't even go to the "Next xFile" line. If I modify the loop to

For i = 1 to xFolder.Files.Count

and do the process that way, it works OK. So, it's not a matter of life-and-death since I can do what I want to do, I just wanted to know if anyone could tell why the "For Each" method hasn't worked.


回答1:


This is a working minimal example:

  1. Create a new file
  2. Reference the Microsoft scripting Runtime
  3. Create a sheet named BGD and write an existing path into C4 e.g. C:\Windows
  4. Paste the code below into a module and run it

This lists the path and all filenames in the debug window.

Public Sub GetData()
    Dim bgd As Worksheet
    Dim myFSO As FileSystemObject
    Dim xFolder As Scripting.Folder
    Dim xFile As Scripting.File


    Set bgd = ThisWorkbook.Sheets("BGD")
    Set myFSO = New FileSystemObject
    Set xFolder = myFSO.GetFolder(bgd.Range("C4").Value)

    Debug.Print xFolder.Path
    For Each xFile In xFolder.Files
        Debug.Print xFile.Name
    Next xFile

End Sub

If you need the variables locally then declare them locally instead of global. Anything else is very bad practice and leads into errors.




回答2:


Ok - turns out the issue was actually with the folder and not the code. As pointed out by @Peh, I should have tested the code with another folder, as well as testing variations of the code itself. When using another folder, the For Each code worked fine. As stated in the OP, I just used For i = 1 to xFolder.Files.Count rather than For Each and got the result I needed, but I prefer the object-led approach of For Each rather than using an integer/long variable to go through the item count, and wanted to know why that method wasn't working.

To get the For Each code working, I copied the desired files to a different folder and it worked perfectly well. As the original folder was a network location, there was possibly some folder permissions or security setting preventing me from using the code I wanted to.




回答3:


I think you want to list all files in all folders and all sub-folders. Check out this link.

http://www.learnexcelmacro.com/wp/2011/11/how-to-get-list-of-all-files-in-a-folder-and-sub-folders/

Download the file; that's the way to go. Once all paths and all file names are listed in your Excel worksheet, you can do all kinds of comparisons, manipulations, and the like.

 Sub GetFilesInFolder(SourceFolderName As String)  

    '--- For Example:Folder Name= "D:\Folder Name\"  

    Dim FSO As Scripting.FileSystemObject  
    Dim SourceFolder As Scripting.folder, SubFolder As Scripting.folder  
    Dim FileItem As Scripting.File  

        Set FSO = New Scripting.FileSystemObject  
        Set SourceFolder = FSO.GetFolder(SourceFolderName)  

        '--- This is for displaying, whereever you want can be configured  

        r = 14  
        For Each FileItem In SourceFolder.Files  
            Cells(r, 2).Formula = r - 13  
            Cells(r, 3).Formula = FileItem.Name  
            Cells(r, 4).Formula = FileItem.Path  
            Cells(r, 5).Formula = FileItem.Size  
            Cells(r, 6).Formula = FileItem.Type  
            Cells(r, 7).Formula = FileItem.DateLastModified  
            Cells(r, 8).Formula = "=HYPERLINK(""" & FileItem.Path & """,""" & "Click Here to Open" & """)"  

            r = r + 1   ' next row number  
        Next FileItem  

        Set FileItem = Nothing  
        Set SourceFolder = Nothing  
        Set FSO = Nothing  
    End Sub  


Sub GetFilesInFolder(SourceFolderName As String, Subfolders As Boolean)  

'--- For Example:Folder Name= "D:\Folder Name\" and Flag as Yes or No  

Dim FSO As Scripting.FileSystemObject  
Dim SourceFolder As Scripting.folder, SubFolder As Scripting.folder  
Dim FileItem As Scripting.File  
'Dim r As Long  
    Set FSO = New Scripting.FileSystemObject  
    Set SourceFolder = FSO.GetFolder(SourceFolderName)  

    '--- This is for displaying, whereever you want can be configured  

    r = 14  
    For Each FileItem In SourceFolder.Files  
        Cells(r, 2).Formula = r - 13  
        Cells(r, 3).Formula = FileItem.Name  
        Cells(r, 4).Formula = FileItem.Path  
        Cells(r, 5).Formula = FileItem.Size  
        Cells(r, 6).Formula = FileItem.Type  
        Cells(r, 7).Formula = FileItem.DateLastModified  
        Cells(r, 8).Formula = "=HYPERLINK(""" & FileItem.Path & """,""" & "Click Here to Open" & """)"  

        r = r + 1   ' next row number  
    Next FileItem  

    '--- This is the Function to go each and Every Folder and get the Files. This is a Nested-Function Calling.  

    If Subfolders = True Then  
        For Each SubFolder In SourceFolder.Subfolders  
            ListFilesInFolder SubFolder.Path, True  
        Next SubFolder  
    End If  

    Set FileItem = Nothing  
    Set SourceFolder = Nothing  
    Set FSO = Nothing  
End Sub 


来源:https://stackoverflow.com/questions/43367671/vba-excel-iterating-through-files-in-folder-via-filesystemobject

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!