Loop through Excel files in subfolders and copy and paste data to one sheet - vba

I'm trying to loop through all Excel files in subfolders of a folder designated by a user and copy and paste data to a new workbook named "Compilation". This code works up to creating and saving a new workbook but data wouldn't copy and paste to the workbook.
Can anyone please help?
Sub LoopCopyPasteSubfolders()
Dim fso As Object
Dim wb As Object
Dim folder As Object
Dim subfolder As Object
Dim MyPath As String
Dim MyFile As String
Dim FdrPicker As FileDialog
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Set FdrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FdrPicker
.Title = "Select a Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
MyPath = .SelectedItems(1) & "\"
End With
NextCode:
'in case of cancel
If MyPath = "" Then GoTo ResetSettings Else
Dim NewWB As Workbook
Set NewWB = Workbooks.Add
ActiveWorkbook.SaveAs Filename:="C:\Batch\Compilation.xlsx", FileFormat:=xlWorkbookNormal
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder = fso.getfolder(MyPath)
Set subfolder = folder.subfolders
For Each subfolder In folder.subfolders
Set wb = subfolder.Files
For Each wb In subfolder.Files
If fso.GetExtensionName(wb.Path) = "*.xls*" Then
Workbooks.Open wb, ReadOnly:=True
Range("A1:M1").End(xlDown).Copy
For Each cell In Workbooks("Compilation").Worksheets("Sheet1").Columns(1).Cells
If IsEmpty(cell) = True Then cell.PasteSpecial Paste:=xlPasteValues
'exit when value pasted to the first empty row
Exit For
Next cell
End If
Next wb
Next subfolder
'reset settings to default
ResetSettings:
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.DisplayAlerts = True
End Sub

Sub LoopCopyPasteSubfoldersIII()
Dim fso As Object
Dim wb As Object
Dim folder As Object
Dim subfolder As Object
Dim MyPath As String
Dim MyFile As String
Dim FdrPicker As FileDialog
Dim wba As Workbook
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Set FdrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FdrPicker
.Title = "Select a Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
MyPath = .SelectedItems(1) & "\"
End With
NextCode:
'in case of cancel
MyPath = MyPath
If MyPath = "" Then GoTo ResetSettings Else
Dim NewWB As Workbook
Set NewWB = Workbooks.Add
NewWB.SaveAs Filename:="C:\Users\405458\Downloads\Compilation.xlsx",
FileFormat:=xlWorkbookNormal
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder = fso.getfolder(MyPath)
For Each subfolder In folder.subfolders
For Each wb In subfolder.Files
If fso.GetExtensionName(wb.Path) = "*.xls*" Then
Set wba = Workbooks.Open(wb.Path & "\" & wb.FullName, , True)
wba.Worksheets(1).Range("A1:M20").Copy
For Each cell In
Workbooks("Compilation").Worksheets("Sheet1").Columns(1).Cells
If IsEmpty(cell) = True Then
cell.PasteSpecial Paste:=xlPasteValues
'exit when value pasted to the first empty row
End If
Exit For
Next cell
wba.Close False
NewWB.Save
End If
Next wb
Next subfolder
'reset settings to default
ResetSettings:
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.DisplayAlerts = True
End Sub

This is finalized code that loops through all subfolders in a folder selected by user and copy and paste data in any Excel files in subfolders to a new workbook.
Sub LoopCopyPasteSubfoldersIII()
Dim fso As Object
Dim wb As Object
Dim folder As Object
Dim subfolder As Object
Dim MyPath As String
Dim MyFile As String
Dim FdrPicker As FileDialog
Dim wba As Workbook
Dim wbn As String
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Set FdrPicker =
Application.FileDialog(msoFileDialogFolderPicker)
With FdrPicker
.Title = "Select a Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
MyPath = .SelectedItems(1) & "\"
End With
NextCode:
'in case of cancel
MyPath = MyPath
If MyPath = "" Then GoTo ResetSettings Else
Dim NewWB As Workbook
Set NewWB = Workbooks.Add
NewWB.SaveAs Filename:="C:\Users\405458\Downloads\Compilation.xlsx",
FileFormat:=xlWorkbookNormal
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder = fso.getfolder(MyPath)
For Each subfolder In folder.subfolders
For Each wb In subfolder.Files
If fso.GetExtensionName(wb.Path) = "xlsx" Then
wbn = fso.GetAbsolutePathName(wb)
Set wba = Workbooks.Open(Filename:=wbn)
ActiveWorkbook.Worksheets(1).Range("A1:M1").Select
Range(Selection, Selection.End(xlDown)).Copy
For Each cell In Workbooks("Compilation").Worksheets("Sheet1").Columns(1).Cells
If IsEmpty(cell) = True Then
cell.PasteSpecial Paste:=xlPasteValues
'exit when value pasted to the first empty row
Exit For
Else
End If
Next cell
wba.Close False
NewWB.Save
End If
Next wb
Next subfolder
'reset settings to default
ResetSettings:
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.DisplayAlerts = True
End Sub

Related

Worksheets(1) Ignore hidden worksheet

I've been working my way through a macro that will merge the first visible worksheet from an entire folder of selected workbooks. With plenty of help, I have the code working for the first worksheet in each workbook, but it is picking up hidden worksheets and I only want the first visible sheet. Here is the code so far:
Option Explicit
Function GetFolder(strPath As String) As String
Dim fldr As FileDialog
Dim sItem As String
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = strPath
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
NextCode:
GetFolder = sItem
Set fldr = Nothing
End Function
Sub CombineFiles()
Dim Path As String
Dim FileName As String
Dim Wkb As Workbook
Dim WS As Worksheet
Application.EnableEvents = False
Application.ScreenUpdating = False
Path = GetFolder("Navigate to folder")
FileName = Dir(Path & "\*.xl??", vbNormal)
Do Until FileName = ""
Set Wkb = Workbooks.Open(FileName:=Path & "\" & FileName, ReadOnly:=True, UpdateLinks:=False)
Wkb.Worksheets(1).Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
Wkb.Close False
FileName = Dir()
Loop
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
you can loop until a visible worksheet is found
Dim i As Long
i = 1
Do While Wkb.Worksheets(i).Visible = False
If i >= Wkb.Worksheets.Count Then
MsgBox "No visible sheet found"
Exit Do
End If
i = i + 1
Loop
Debug.Print Worksheets(i).Name 'first visible sheet

How to loop through all sheets in all workbooks within a folder

I use a macro to make changes on each sheet of each workbook in a given folder on my computer.
Sequence of events:
Open each Excel file within the user-selected folder
Perform a task on each sheet in the workbook
Save the file
Close the workbook
The macro doesn't work. The problem seems to be arising from Selection.AutoFilter.
Sub LoopAllExcelFilesInFolder()
'OBJECTIVE: To loop through all Excel files in a user specified folder and perform a set task on them
'SOURCE: www.TheSpreadsheetGuru.com
Dim wb As Workbook
Dim Current As Worksheet
Dim myPath As String
Dim myFile As String
Dim myExtension As String
Dim FldrPicker As FileDialog
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
'Retrieve Target Folder Path From User
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
myPath = .SelectedItems(1) & "\"
End With
'In Case of Cancel
NextCode:
myPath = myPath
If myPath = "" Then GoTo ResetSettings
'Target File Extension (must include wildcard "*")
myExtension = "*.xlsx*"
'Target Path with Ending Extention
myFile = Dir(myPath & myExtension)
'Loop through each Excel file in folder
Do While myFile <> ""
'Set variable equal to opened workbook
Set wb = Workbooks.Open(Filename:=myPath & myFile)
'Ensure Workbook has opened before moving on to next line of code
DoEvents
'Task: For each worksheet, delete the first column, make A1 bold, and filter and remove all rows in column A that do not contain anything
For Each Current In wb.Worksheets
Columns("A:A").Select
Selection.Delete Shift:=xlToLeft
Range("A1").Select
Selection.Font.Bold = True
Selection.AutoFilter
ActiveSheet.Range("$A$1:$A$5000").AutoFilter Field:=1, Criteria1:="="
Rows("2:2").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Delete Shift:=xlUp
ActiveSheet.ShowAllData
Range("A1").Select
Next
'Save and Close Workbook
wb.Close SaveChanges:=True
'Ensure Workbook has closed before moving on to next line of code
DoEvents
'Get next file name
myFile = Dir
Loop
'Message Box when tasks are completed
MsgBox "Task Complete!"
ResetSettings:
'Reset Macro Optimization Settings
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
You should try it like this.
Sub Example()
Dim MyPath As String, FilesInPath As String
Dim MyFiles() As String, Fnum As Long
Dim mybook As Workbook
Dim CalcMode As Long
Dim sh As Worksheet
Dim ErrorYes As Boolean
'Fill in the path\folder where the files are
MyPath = "C:\Users\Ron\test"
'Add a slash at the end if the user forget it
If Right(MyPath, 1) <> "\" Then
MyPath = MyPath & "\"
End If
'If there are no Excel files in the folder exit the sub
FilesInPath = Dir(MyPath & "*.xl*")
If FilesInPath = "" Then
MsgBox "No files found"
Exit Sub
End If
'Fill the array(myFiles)with the list of Excel files in the folder
Fnum = 0
Do While FilesInPath <> ""
Fnum = Fnum + 1
ReDim Preserve MyFiles(1 To Fnum)
MyFiles(Fnum) = FilesInPath
FilesInPath = Dir()
Loop
'Change ScreenUpdating, Calculation and EnableEvents
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
End With
'Loop through all files in the array(myFiles)
If Fnum > 0 Then
For Fnum = LBound(MyFiles) To UBound(MyFiles)
Set mybook = Nothing
On Error Resume Next
Set mybook = Workbooks.Open(MyPath & MyFiles(Fnum))
On Error GoTo 0
If Not mybook Is Nothing Then
'Change cell value(s) in one worksheet in mybook
On Error Resume Next
With mybook.Worksheets(1)
If .ProtectContents = False Then
.Range("A1").Value = "My New Header"
Else
ErrorYes = True
End If
End With
If Err.Number > 0 Then
ErrorYes = True
Err.Clear
'Close mybook without saving
mybook.Close savechanges:=False
Else
'Save and close mybook
mybook.Close savechanges:=True
End If
On Error GoTo 0
Else
'Not possible to open the workbook
ErrorYes = True
End If
Next Fnum
End If
If ErrorYes = True Then
MsgBox "There are problems in one or more files, possible problem:" _
& vbNewLine & "protected workbook/sheet or a sheet/range that not exist"
End If
'Restore ScreenUpdating, Calculation and EnableEvents
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
https://www.rondebruin.nl/win/s3/win010.htm

VBA Looping through excel files in selected directory - Copy data and paste in different sheets

I'm looking to select a directory and then loop through each xlsm file within that directory. For each loop it should open the file, copy a range and paste into the current workbook under a specific sheet.
I.e. the first file will paste into sheet1 the second opened file will past into sheet 2, and so on.
I have some code, now I need help to get it to paste the rang into a sheets.count? or something like that. At the moment it just pastes into sheet 1 because that is static.
Sub Test()
Dim wb As Workbook, wb1 As Workbook
Dim myPath As String
Dim myFile As String
Dim myExtension As String
Dim FldrPicker As FileDialog
Set wb1 = Workbooks(ThisWorkbook.Name)
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
'Retrieve Target Folder Path From User
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
myPath = .SelectedItems(1) & "\"
End With
'In Case of Cancel
NextCode:
myPath = myPath
If myPath = "" Then GoTo ResetSettings
'Target File Extension (must include wildcard "*")
myExtension = "*.xlsm"
'Target Path with Ending Extention
myFile = Dir(myPath & myExtension)
'Loop through each Excel file in folder
Do While myFile <> ""
'Set variable equal to opened workbook
Set wb = Workbooks.Open(Filename:=myPath & myFile)
'Ensure Workbook has opened before moving on to next line of code
DoEvents
'Copy data from opened workbook
wb.Sheets("HI Sub-segment split").Range("A1:Z1").Copy
'Paste data into destination workbook
wb1.Sheet(1).Range("A1:Z1").PasteSpecial xlPasteValues
'Close Workbook
wb.Close
'Ensure Workbook has closed before moving on to next line of code
DoEvents
'Get next file name
myFile = Dir
Loop
'Message Box when tasks are completed
MsgBox "Import Complete!"
ResetSettings:
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
Worked with this...
Sub Testing()
'
'
'
Dim wb As Workbook, wb1 As Workbook
Dim myPath As String
Dim myFile As String
Dim myExtension As String
Dim FldrPicker As FileDialog
Dim loop_ctr As Integer
Set wb1 = Workbooks(ThisWorkbook.Name)
loop_ctr = 1
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
'Retrieve Target Folder Path From User
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
myPath = .SelectedItems(1) & "\"
End With
'In Case of Cancel
NextCode:
myPath = myPath
If myPath = "" Then GoTo ResetSettings
'Target File Extension (must include wildcard "*")
myExtension = "*.xls*"
'Target Path with Ending Extention
myFile = Dir(myPath & myExtension)
'Loop through each Excel file in folder
Do While myFile <> ""
'Set variable equal to opened workbook
Set wb = Workbooks.Open(Filename:=myPath & myFile)
'Ensure Workbook has opened before moving on to next line of code
DoEvents
'Copy data from opened workbook
wb.Sheets("Sheet1").Range("A1:B2").Copy
'Paste data into destination workbook
wb1.Sheets(loop_ctr).Range("A1:B2").PasteSpecial xlPasteValues
'Close Workbook
wb.Close
'Ensure Workbook has closed before moving on to next line of code
DoEvents
'Get next file name
myFile = Dir
'Update loop_ctr value
loop_ctr = loop_ctr + 1
Loop
'Message Box when tasks are completed
MsgBox "Import Complete!"
ResetSettings:
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub

Grabbing data from multiple excel files and copy them in a summary sheet

Whenever I run this code I get: Run-time error '9' Subscript out of range. Can't figure out how to fix this error, please help.
The code runs trough excel files in a selected folder and copy pastes the selected row.
In the next step I would like to extend the code, to store and sum each cell value like this:
var1 = var1 + range("A5").value
But first please help me how to fix this error. Thank you.
Sub LoopAllExcelFilesInFolder()
Dim OutputWs As Worksheet
Dim myPath As String
Dim myFile As String
Dim myExtension As String
Dim FldrPicker As FileDialog
Dim Lastrow As Long
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
'Retrieve Target Folder Path From User
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
myPath = .SelectedItems(1) & "\"
End With
'In Case of Cancel
NextCode:
myPath = myPath
If myPath = "" Then GoTo ResetSettings
'Target File Extension
myExtension = "*.xlsx"
'Target Path with Ending Extention
myFile = Dir(myPath & myExtension)
'set output worksheet
OutputWs = ThisWorkbook.Worksheets(Test)
'Loop through each Excel file in folder
Do While myFile <> ""
Workbooks.Open (myPath & myFile)
Range("A1:D3").Copy
ActiveWorkbook.Close
Lastrow = OutputWs.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
ActiveSheet.Paste Destination:=Worksheets("Test").Range(Cells(Lastrow, 1), Cells(Lastrow, 4))
'Get next file name
myFile = Dir()
Loop
'Message Box when tasks are completed
MsgBox "Task Complete!"
ResetSettings:
'Reset Macro Optimization Settings
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
To set an object reference to your worksheet, you need the keyword Set included:
Set OutputWs = ThisWorkbook.Worksheets("yoursheetname")
The get next file name should also be myFile = Dir and not include the parenthesis.
I took a closer look at the code and it appears that you're not explicitly defining which books are which in each case, meaning that the "orphaned" range statements can cause you problems. The 1004 error though is coming from your Paste statement, which I have corrected for you in the following code:
Sub LoopAllExcelFilesInFolder()
Dim OutputWs As Worksheet
Dim oNewBook As Workbook
Dim myPath As String
Dim myFile As String
Dim myExtension As String
Dim FldrPicker As FileDialog
Dim Lastrow As Long
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
'Retrieve Target Folder Path From User
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
myPath = .SelectedItems(1) & "\"
End With
'In Case of Cancel
NextCode:
myPath = myPath
If myPath = "" Then GoTo ResetSettings
'Target File Extension
myExtension = "*.xlsx"
'Target Path with Ending Extention
myFile = Dir(myPath & myExtension)
'set output worksheet
Set OutputWs = ThisWorkbook.Worksheets("Test")
'Loop through each Excel file in folder
Do While myFile <> ""
Set oNewBook = Workbooks.Open(myPath & myFile)
oNewBook.Worksheets(1).Range("A1:D3").Copy
oNewBook.Close
Lastrow = OutputWs.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
With OutputWs
Lastrow = .Cells(.Rows.Count, 1).End(xlUp).Offset(1, 0).Row
OutputWs.Paste .Range("A" & Lastrow & ":" & "D" & Lastrow)
End With
'Get next file name
myFile = Dir
Loop
'Message Box when tasks are completed
MsgBox "Task Complete!"
ResetSettings:
'Reset Macro Optimization Settings
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
Note that this code assumes that you want to copy from the first worksheet of the opened workbook (hence the oNewBook.Worksheets(1) added to the Range.Copy statement)

Import text files to excel and create master workbook

I am a grad student and I collect a lot of data that is stored in txt files. I want to import the text files as a fixed width, columns a, b and c all are 12, then save those files as excel files and then move them into a master workbook. I found the following code that worked for making the master workbook but it does not import them in numerical order.
I am using Microsoft 2010.
Sub Merge2MultiSheets()
Dim wbDst As Workbook
Dim wbSrc As Workbook
Dim wsSrc As Worksheet
Dim MyPath As String
Dim strFilename As String
Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False
MyPath = "C:\Users\Kyle\Desktop\Scan Rate Study 1-14-16"
Set wbDst = Workbooks.Add(xlWBATWorksheet)
strFilename = Dir(MyPath & "\*.xls", vbNormal)
If Len(strFilename) = 0 Then Exit Sub
Do Until strFilename = ""
Set wbSrc = Workbooks.Open(Filename:=MyPath & "\" & strFilename)
Set wsSrc = wbSrc.Worksheets(1)
wsSrc.Copy After:=wbDst.Worksheets(wbDst.Worksheets.Count)
wbSrc.Close False
strFilename = Dir()
Loop
wbDst.Worksheets(1).Delete
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
Consider using the FSO object to traverse the MyPath directory and copy over the .xls files. Currently, your set up was importing all Excel like files located in directory:
Sub Merge2MultiSheets()
Dim MyPath As String
Dim wbDst As Workbook, wbSrc As Workbook, wsSrc As Worksheet
Dim fso As Object, olFolder As Object, olFile As Object
Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False
MyPath = "C:\Users\Kyle\Desktop\Scan Rate Study 1-14-16"
Set wbDst = Workbooks.Add(xlWBATWorksheet)
Set fso = CreateObject("Scripting.FileSystemObject")
Set olFolder = fso.GetFolder(MyPath)
For Each olFile In olFolder.Files
If Right(olFile.Name, 4) = ".xls" Then
Set wbSrc = Workbooks.Open(olFile.Name)
Set wsSrc = wbSrc.Worksheets(1)
wsSrc.Copy After:=wbDst.Worksheets(wbDst.Worksheets.Count)
wbSrc.Close False
End If
Next olFile
wbDst.Worksheets(1).Delete
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True
Set olFile = Nothing
Set olFolder = Nothing
Set fso = Nothing
End Sub