arraysexcelvbamultidimensional-arrayexcel-tables

Keep Array value when Sub is looping


I currently have this code that finds all files and folders and writes it to a table. The problem is is that is it sometimes slow.

The code below is modified so that it writes to an array but I am having issues passing the array on when the code loops.

Ultimately, I would like the array to pass on to the first sub so that I can transpose it into the table at once.

Sub FileAndFolder()

Dim FSOLibrary As Object
Dim FSOFolder As Object
Dim FolderName As String
Dim FilesTbl As ListObject
Set FilesTbl = Range("FilesTbl").ListObject

'Set the folder name to a variable
FolderName = Left$(ActiveWorkbook.Path, InStrRev(ActiveWorkbook.Path, "\"))

'Set the reference to the FSO Library
Set FSOLibrary = CreateObject("Scripting.FileSystemObject")

'Another Macro must call LoopAllSubFolders Macro to start
LoopAllFolders FSOLibrary.GetFolder(FolderName)

'return TempArray here and paste into table

'Range(FilesTbl.ListColumns("File Name").DataBodyRange(1)) = TempArray

End Sub

Sub LoopAllFolders(FSOFolder As Object)
'Don’t run the following macro, it will be called from the macro above

Dim FSOSubFolder As Object
Dim FSOFile As Object
Dim FolderPath As String
Dim FileName As String
Dim TempArray() As String

'For each subfolder call the macro
For Each FSOSubFolder In FSOFolder.SubFolders
    LoopAllFolders FSOSubFolder
Next

'For each file, print the name
For Each FSOFile In FSOFolder.Files

    'Insert the actions to be performed on each file
    FileName = FSOFile.Name
    FolderPath = FSOFile.ParentFolder
          
    If Left(FileName, 2) = "~$" Then GoTo NEXTINLOOP
    ReDim Preserve TempArray(0 To 3, 0 To i)
        
    TempArray(0, i) = FileName
    TempArray(1, i) = FolderPath & "\" & FileName 'file
    TempArray(2, i) = FolderPath 'folder
    TempArray(3, i) = FolderPath & "\" & FileName 'showpath
        
    i = i + 1
NEXTINLOOP:
Next
 
End Sub 'TempArray and i clears here

Thanks.


Solution

  • You either need to declare a variable at the module level so that the list of folder information is available to all methods in the module, or change 'LoopAllFolders' to a Function so that you can return the information you have collated.

    The function below will return a Variant which contains an array of arrays (normally called a jagged array). You access the jagged array using this nomenclature

    Varname(x)(y)
    

    You will need a variable in the calling method to receive the jagged array

    e.g.

    Dim myFileInfo as Variant
    MyFileInfo = LoopAllFolders(FSOLibrary.GetFolder(FolderName))
    
    

    Here is the updated function

    Public Function LoopAllFolders(FSOFolder As Scripting.FileSystemObject) As Variant
    'Don’t run the following macro, it will be called from the macro above
    
        Dim FileInfo As Scripting.Dictionary: Set myFileInfo = New Scripting.Dictionary
    
    'For each subfolder call the macro
    
        Dim FSOSubFolder As Scripting.Folder
        For Each FSOSubFolder In FSOFolder.SubFolders
            LoopAllFolders FSOSubFolder
        Next
    
        'For each file, print the name
        Dim FSOFile As Scripting.File
        For Each FSOFile In FSOFolder.Files
    
            'Insert the actions to be performed on each file
            Dim FileName As String
            FileName = FSOFile.Name
        
            Dim FolderPath As String
            FolderPath = FSOFile.ParentFolder
              
            If Not Left(FileName, 2) = "~$" Then
        
                myFileInfo.Add Array(FileName, FolderPath & "\" & FileName, FolderPath, FolderPath & "\" & FileName)
            
            End If
        
        Next
    
        LoopAllFolders = myFileInfo.Items
     
    End Function
    

    The above code may not be perfect but at least it points you in the right direction.

    Based on your question, you might do well by working through a VBA tutorial as functions are fairly fundamental, and if you are unaware of them......

    To help you on your journey I'd also recommend installing the fantastic and free RubberDuck addin.