3

I am trying to consolidate Excel files from different folders to a single folder. Within each folder there is a single Excel file.

Sub move_data()

Dim FSO As Object
Dim FromPath As String
Dim ToPath As String
Dim Fdate As Date
Dim FileInFromFolder As Object

MkDir "C:\User\TEST\"        
FromPath = "C:\User\MainFolder\" 
ToPath = "C:\User\TEST\"     
    
Set FSO = CreateObject("scripting.filesystemobject")

If FSO.FolderExists(FromPath) = False Then
    MsgBox FromPath & " doesn't exist"
    Exit Sub
End If

For Each FileInFromFolder In FSO.GetFolder(FromPath).Files
    FileInFromFolder.Move ToPath
Next FileInFromFolder

End Sub

The code is unable to get the files from the subfolder within the folder (as shown in the image).

The area I am looking to change is 'FromPath', if it is possible to include a wildcard to specify the subfolders?

Multiple Folders, One Excel file per Folder
enter image description here

Community
  • 1
  • 1
  • [This](https://stackoverflow.com/questions/68246938/get-file-list-from-folders-and-subfolders-excel-vba) will help you to loop trough folders and subfolders. Just adapt it to move only Excel files – Foxfire And Burns And Burns Apr 21 '22 at 11:14

2 Answers2

2

Move Files From Multiple Folders to Single Folder (FileSystemObject)

Sub MoveFiles()

    Const FromPath As String = "C:\MainFolder\"
    Const ToPath As String = "C:\Test\"
    Const LCaseExtensionPattern As String = "xls*"
    
    Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
    
    If Not fso.FolderExists(FromPath) Then
        MsgBox "The folder '" & FromPath & "' doesn't exist.", vbCritical
        Exit Sub
    End If
    
    If Not fso.FolderExists(ToPath) Then MkDir ToPath
    
    Dim SubFolderPaths() As String: SubFolderPaths = ArrSubFolderPaths(FromPath)
    
    Dim fsoFile As Object
    Dim NotMoved() As String
    Dim n As Long
    Dim mCount As Long
    Dim nmCount As Long
    
    For n = 0 To UBound(SubFolderPaths)
        For Each fsoFile In fso.GetFolder(SubFolderPaths(n)).Files
            If LCase(fso.GetExtensionName(fsoFile)) _
                    Like LCaseExtensionPattern Then
                If Not fso.FileExists(ToPath & fsoFile.Name) Then
                    mCount = mCount + 1
                    fsoFile.Move ToPath
                Else
                    nmCount = nmCount + 1
                    ReDim Preserve NotMoved(1 To nmCount)
                    NotMoved(nmCount) = fsoFile.Path
                End If
            End If
        Next fsoFile
    Next n
 
    Dim MsgString As String
    MsgString = "Files moved: " & mCount & "(" & mCount + nmCount & ")"
    If nmCount > 0 Then
        MsgString = MsgString & vbLf & vbLf & "Files not moved: " & mCount _
            & "(" & mCount + nmCount & "):" & vbLf & vbLf & Join(NotMoved, vbLf)
    End If
    
    MsgBox MsgString, vbInformation
    
End Sub


Function ArrSubFolderPaths( _
    ByVal InitialFolderPath As String, _
    Optional ByVal ExcludeInitialFolderPath As Boolean = False) _
As String()
    Const ProcName As String = "ArrSubFolderPaths"
    On Error GoTo ClearError
    
    ' Ensure that a string array is passed if an error occurs.
    Dim Arr() As String: Arr = Split("") ' LB = 0 , UB = -1
    
    ' Locate the trailing path separator.
    Dim pSep As String: pSep = Application.PathSeparator
    If Right(InitialFolderPath, 1) <> pSep Then
        InitialFolderPath = InitialFolderPath & pSep
    End If
    
    ' Add the initial folder path to a new collection.
    Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
    Dim coll As Collection: Set coll = New Collection
    coll.Add fso.GetFolder(InitialFolderPath)
    
    ' Add the initial folder path (or don't) to the result.
    Dim n As Long
    If ExcludeInitialFolderPath Then ' don't add
        n = -1
    Else ' add
        ReDim Preserve Arr(0 To 0): Arr(0) = coll(1)
    End If
    
    Dim fsoFolder As Object
    Dim fsoSubFolder As Object
    
    Do While coll.Count > 0
        Set fsoFolder = coll(1)
        coll.Remove 1
        For Each fsoSubFolder In fsoFolder.SubFolders
            coll.Add fsoSubFolder
            n = n + 1: ReDim Preserve Arr(0 To n): Arr(n) = fsoSubFolder
        Next fsoSubFolder
    Loop

    ArrSubFolderPaths = Arr

ProcExit:
    Exit Function
ClearError:
    Debug.Print "'" & ProcName & "' Run-time error '" _
        & Err.Number & "':" & vbLf & "    " & Err.Description
    Resume ProcExit
End Function
VBasic2008
  • 44,888
  • 5
  • 17
  • 28
  • Thank you so much! This code works and it helped to copy all of the Excel files from the subfolder. Are we able to make a slight tweak to the code to only grab this specific file named 'DPP General Template Day X Block A.xlsx'? Where Day X changes based on the folder date. E.g. 'Day 13' for the folder '13.11.2021' – Jeremy Wong Apr 22 '22 at 00:32
  • After the `If LCase... Then` line, add another `If` statement: `If Instr(1, fsoFile.Name, "DPP General Template Day", vbTextCompare) = 1 Then` (i.e. begins with). and don't forget the 'closing' `End If`. – VBasic2008 Apr 22 '22 at 06:07
1

This is simple to achieve if you adopt recursive procedure.

Sub Starter()
    Call FilesMover("C:\User\MainFolder\", "C:\User\TEST\")
End Sub

Sub FilesMover(FromPath As String, DestinationPath As String)
    Dim fso As object
    Set fso = CreateObject("scripting.filesystemobject")
    Dim f As File
    Dim d As Folder
    
    ' first move the files in the folder
    For Each f In fso.GetFolder(FromPath).Files
        f.Move DestinationPath
    Next f
    
    ' then check the subfolders
    For Each d In fso.GetFolder(FromPath).SubFolders
        Call FilesMover(d.Path, DestinationPath)
    Next d
End Sub
Rosetta
  • 2,665
  • 1
  • 13
  • 29
  • This works! Thank you so much! But are you to advise on how we can further edit the code so to move a specific Excel file? Within the folder there are multiple Excel files and I am just looking to move a single file. Say the file name is 'DPP General Template Day X Block A.xlsx'? Where Day X changes based on the folder date. E.g. 'Day 13' for the folder '13.11.2021' – Jeremy Wong Apr 22 '22 at 00:50
  • @JeremyWong you can use the `If..Else..End If` to move files conditionally. You can refer this doc https://learn.microsoft.com/en-us/office/vba/language/concepts/getting-started/using-ifthenelse-statements. The file name get be obtained using `f.name` – Rosetta Apr 22 '22 at 10:49