Create loop to open multiple files and copy data to a master file in VBA excel - vba

I have multiple files with data that need to be transposed into a single master file with all the data into a single row.
I'm a complete noob in programming so if the code I have so far doesn't make any sense, then please feel free to change it
I was able to find this "Loop all excel files in a folder" code from www.TheSpreadsheetGuru.com The code works perfectly fine, it will open up each file individually in the folder and then close it, and then open the next file and close it until it has gone through every file in that folder.
However, I'd like to insert a "copy and paste data" code loop within the loop. So what needs to happen is, the code will open "File1" in the folder, and then copy and paste the data into the "Master File" in cell A4. Then it will close "File1", and then open up "File2" and copy the data into "Master File" in cell A5 and then close "File2". It will repeat this until all files in the folder have been opened/closed.
This is the code I have right now, but I can't get the copy and paste code to work properly. I'm having a hard time figuring out how to set the loop up where the code will know what file it is currently on and setting a counter for the cell of the Master File that it is pasting into.
Sub LLoopAllExcelFilesInFolder()
'PURPOSE: 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 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 = "March"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
myPath = .SelectedItems(1) & "\"
End With
'In Case of Cancelhow
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)
'THIS IS MY COPY AND PASTE CODE (DOESN'T WORK)
Dim row As Integer
While row = 4
Workbooks("Filename:=myPath & myFile").Worksheets("Resin Log").cell("I5") = Workbooks("Workbook1.xlsm").Worksheets("Sheet1").Range("A" & row).Value
Next row
'Save and Close Workbook
wb.Close SaveChanges:=False
'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

It is possible to do what you're talking about. I would suggest, trying to just set cell values in the file being created directly
targetworkbook.worksheets(1).Range("A1").value = sourceworkbook.Worksheets(1).Range("C4").value
rather than using .Copy & .Paste so that if the macro takes a while to run you aren't locked out of using Copy/Paste in other applications. If you're still unsure of what to do, try doing it with Record Macro turned on. The generated code will need tweaked, but will give you most of what you need.
Also, be sure to look at this link for some other things to avoid using in your code.

Related

VBA code not looping completely through every folder

So my question has been marked as a possible Duplicate of VBA Loop through folder and subfolders to find specific sheet then Copy and Paste certain data
This is indeed my question and it is practically the same. The part I am struggling with is getting automation from the first folder through to the rest
I think the piece of code that is relevant for change is here
For Each ChildFolder In FSO.GetFolder(MyFolder).SubFolders
myFile = Dir(MyFolder & ChildFolder.Name & "\") 'DIR gets the first file of the folder
I have no desire to upset the ethics of the site. I simply accepted an answer and struggled with the code I had after changes happened in the workplace.
Original Question Below
I hope you can help. I have a piece of code and its works fine. Essentially it allows a user to click on a command button (see Pic 5) on an Excel Workbook opens a dialog box allows the user to select a folder then once the folder is selected the code loops through the folder for files named Like "CustomerExp" then copies and pastes information on this Like "CustomerExp" Excel sheet to another Excel sheet called rejects in the Workbook where the Command Button is held.
The only issue I have is that it still requires some manual input from the user.
The issue I am facing is this: I have a folder 2017 it is stored here X:\Operations\Rejections all Markets see Pic 1
Within folder 2017 I have more folders named for months of the year. See Pic 2
Within each monthly folder lets take Jan for example there will be several more folders see Pic 3
Withing each folder inside the monthly folder there are excel sheets saved see Pic 4
As i said my code does actually work but what the user has to do is select a monthly folder each time. So the user clicks the command button navigates to Jan folder double clicks on Jan folder and the code works. Then the user has to double click on Feb folder and the code works again and then onto March.
What I want is for the user to click only on folder 2017 and the code will then go through Jan and all its folders find files named Like "CustomerExp" do the copy and paste then move onto Feb and then March and so forth without any input or double clicking on each monthly folder by the user. I'm looking for full automation from the click on the 2017 folder.
My code is below can it be amended to provide full automation from the 2017 folder.
As always any and all help is greatly appreciated.
MY CODE
Sub AllWorkbooks()
Dim MyFolder As String 'Path collected from the folder picker dialog
Dim myFile As String 'Filename obtained by DIR function
Dim wbk As Workbook 'Used to loop through each workbook
Dim FSO As New FileSystemObject ' Requires "Windows Script Host Object Model" in Tools -> References
Dim ParentFolder As Object, ChildFolder As Object
Dim wb As Workbook
Dim myPath As String
Dim myExtension As String
Dim FldrPicker As FileDialog
Dim lRow As Long
Dim ws2 As Worksheet
Dim y As Workbook
On Error Resume Next
Application.ScreenUpdating = False
'Opens the folder picker dialog to allow user selection
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Please select a folder"
.Show
.AllowMultiSelect = False
If .SelectedItems.Count = 0 Then 'If no folder is selected, abort
MsgBox "You did not select a folder"
Exit Sub
End If
MyFolder = .SelectedItems(1) & "\" 'Assign selected folder to MyFolder
End With
myFile = Dir(MyFolder) 'DIR gets the first file of the folder
Set y = ThisWorkbook
Set ws2 = y.Sheets("Rejects")
'Loop through all files in a folder until DIR cannot find anymore
Do While myFile <> ""
If myFile Like "*CustomerExp*" Then
'Opens the file and assigns to the wbk variable for future use
Set wbk = Workbooks.Open(Filename:=MyFolder & myFile)
'Replace the line below with the statements you would want your macro to perform
With wbk.Sheets(1)
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("A1:AA" & lRow).Copy ws2.Range("A" & Rows.Count).End(xlUp)(2)
End With
''Application.Wait (Now + TimeValue("0:00:05"))
wbk.Close savechanges:=True
End If
myFile = Dir 'DIR gets the next file in the folder
Loop
For Each ChildFolder In FSO.GetFolder(MyFolder).SubFolders
myFile = Dir(MyFolder & ChildFolder.Name & "\") 'DIR gets the first file of the folder
'Loop through all files in a folder until DIR cannot find anymore
Do While myFile <> ""
If myFile Like "*CustomerExp*" Then
'Opens the file and assigns to the wbk variable for future use
Set wbk = Workbooks.Open(Filename:=MyFolder & ChildFolder.Name & "\" & myFile)
'Replace the line below with the statements you would want your macro to perform
With wbk.Sheets(1)
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("A1:AA" & lRow).Copy ws2.Range("A" & Rows.Count).End(xlUp)(2)
End With
''Application.Wait (Now + TimeValue("0:00:05"))
wbk.Close savechanges:=True
End If
myFile = Dir 'DIR gets the next file in the folder
Loop
Next ChildFolder
Application.ScreenUpdating = True
End Sub
Pic 1
Pic 2
Pic 3
Pic 4
Pic 5

Automating the Process of Renaming the Column Names in Multiple Excel Sheets

I have a requirement from the client in which they want us to rename the column from multiple excel sheets which are present in the same directory.
There are 70+ excel reports and we are not sure that the particular column is present in which excel file. So every time they ask us to change, all the time we have to drill down all the excel sheets to find out the changes required which is really time consuming.
I thought of automating the process. Since all the files are present under the same directory, can't we use a MACRO,BATCH/UNIX SCRIPTS or any other way by which we can traverse the entire directory and make those changes by performing a find and replace thing.
So my first question is, if this is feasible ? If yes, then can anyone suggest/advice how to work around on this process ?
Thanks in Advance
I can't take full credit for the below as this is a patchwork of code I have used over the years. This is how I would go about it personally:
Manually make a copy of the files to change and place them in a folder (keep the originals safe!)
Let the code open each file and change it
Code will save a copy in a different 'done' folder
The example below loops through each Excel file and moves it from the 'to-do' folder to the 'done' folder once it has changed the cell "A1" to "Hello World". When the 'to-do' folder is empty the code stops.
You'll need to change the file paths for this to work.
Sub Example()
Dim FolderPath As String, FilePath As String, FileCount As Integer
Dim objExcelApp As Object
Dim wb As Object
Dim SaveName As String
FolderPath = "C:\Users\********\Desktop\To Do\"
NewFolderPath = "C:\Users\********\Desktop\Done\"
FilePath = FolderPath & "*.xl??"
FileName = Dir(FilePath)
ChangeNextFile:
FileCount = 0
'count how many files in "files to be changed" folder
Do While FileName <> ""
FileCount = FileCount + 1
FileName = Dir()
Loop
'if there are no files left end the code
If FileCount = 0 Then GoTo FinishedLoadingFiles
'choose the first file to change
FileName = Dir(FilePath)
Debug.Print FileName
'create an instance of Excel
Set objExcelApp = CreateObject("Excel.Application")
With objExcelApp
.Visible = False
.DisplayAlerts = False
End With
'opens the excel file in the background
objExcelApp.Workbooks.Open FileName:=FolderPath & FileName, UpdateLinks:=False
Set wb = objExcelApp.ActiveWorkbook
objExcelApp.ActiveWindow.Activate
'changes cell "A1" to say "hellow world"
wb.Sheets(1).Cells(1, 1).Value = "Hello World"
'saves the file in the done pile
wb.saveas NewFolderPath & FileName '& ".xlsb"
'closes excel
With objExcelApp
.DisplayAlerts = True
End With
wb.Close
objExcelApp.Quit
Set wb = Nothing
Set objExcelApp = Nothing
'deletes the original file. New file has been saved in the new folder
Kill FolderPath & FileName
GoTo ChangeNextFile
FinishedLoadingFiles:
MsgBox "All done"
End Sub

VBA: How to delete Column "A" in a specific Folder with different files with Sheet name that varies

I have a folder in my Desktop with more or less 2000 csv files. Those files have only 1 "Sheet" but the sheet name varies. The only similar thing is that it starts with the word "Tankard".
In that one sheet, I just need to remove Column A and Save it, for all 2000 files. Its only my 2nd month to explore vba automation at work. I'd appreciate if someone can help me. Thanks in advance.
Script:
Sub Tank()
Dim wb As Workbook
Dim myPath As String
Dim myfile As String
Dim myExtension As String
Dim SheetName As String
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
SheetName = "Tankard*"
myPath = "\\ph00winfdfs01p\shares\JoeyC\documents\Roaming\Windows\Desktop\Tank\"
If myPath = "" Then GoTo ResetSettings
'Target File Extension (must include wildcard "*")
myExtension = "Tankard*.csv"
'Target Path with Ending Extention
myfile = Dir(myPath & myExtension)
'Loop through each Excel file in folder
For i = 1 To 201
Set wb = Workbooks.Open(Filename:=myPath & myfile)
';;;;;;;;;;;;;;WRITE YOUR CODE HERE
Sheets("SheetName").Select
Columns("A").Select
Selection.Delete
wb.Close SaveChanges:=True
Next i
'Get next file name
myfile = Dir
'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
Try to understand what's happening. What this sub does at the moment is opening the first workbook that Dir can find, opening it 201 times and deleting the first column of sheet "Sheetname" every time.
Sheets("SheetName").Select
This selects the sheet with the name "Sheetname", not the name with the value that you set the string Sheetname to. If anything, it should be Sheets(Sheetname) but wildcards don't work here anyways.
Now let's look at the process you're trying to achieve.
myfile = Dir(myPath & myExtension)
sets myfile to the first file that matches your pattern ...\Tankard*.csv
Set wb = Workbooks.Open(Filename:=myPath & myfile)
opens the file and now you can access the workbook via wb
To delete the first column on the sheet I would recommend selecting all that stuff but deleting the range directly:
wb.Sheets(1).Columns(1).Delete 'If you want to actually delete the column
wb.Sheets(1).Columns(1).Clear 'If you want to just remove the values
As you can see you don't need the name of the sheet at all. Now save the workbook:
wb.Close SaveChanges:=True
Now you can set myfile to the next filename using Dir:
myfile = Dir
Then repeat that until there are no more files (at that point Dir will return "". The best way to achieve that is to use a While loop, e.g. like this
While myfile <> ""
'Do stuff here
Wend '(While End)
The advantage over a For loop is that you don't need to know the exact number of files in your folder.
I'll leave it up to you to patch that all together.

'Workbook.open' error - Closes the file right after opening it

I need to get data on one hundred Excel workbooks. I created a macro to loop through those files, get the data and close them. But right after my Workbooks.open(path) opens the file, it closes it and throws a 1004 error saying that the method 'open' failed.
I tried to open another of those one hundred files and every one of them throws the same error. I tried to open a normal file (not one of those one hundred), through the macro, it opens normally.
Copied a bunch of those to my C:\, all of them throw an error.
Recorded a macro to open the file. The file opens because I clicked File->Open File, but it throws an error if I run the macro to open it.
Obviously the problem lies in those files.
LINK to the file.
--> CODE:
Just a normal Workbook.open code (There is no full code, it's just it! And I get an error with the file linked)
Workbook.Open("C:\file.xlsx")
--> They Open normally by hand without any error or problem.
--> They have:
* Querytables
* Normal formulas
* They are kinda small
--> Observations and what I tried:
The paths are right (it opens the file and closes it right after, and error).
The files I'm trying to open have connection queries, but I deleted the connections on my test files. Same error.
Tried the CurruptLoad param, same error (I don't know if I used it right).
Tried UpdateLinks:=0, same error.
Tried to open it through new Excel.Application, nothing changed.
Tried on another PC, same thing.
Anyone had something like this?
What should I try?
What are you doing after the open ?
If you are trying to do something else, then maybe file has not opened completely and error is based on next line not happening.
Solution I found for this case (here in my work)
Application.DisplayAlerts = False
set wb = Workbooks.Open(objFile.path, ReadOnly:=True, CorruptLoad:=xlExtractData)
wb.close
Application.DisplayAlerts = True
Through the CorruptLoad:=xlExtractData, it clear every table, every connection, and anything else that could be problem. I get my data and close the file without saving it.
Thanks for the support guys.
If I understand your problem you can use one code that I use when I need to retrieve data from plus files (all with the same formatting )
Sub ImportData()
Dim wb 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
WsTo = ActiveWorkbook.Name
'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 Exit Sub
'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)
'Change First Worksheet's Background Fill Blue
Sheets(1).Select
Range("A1").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
WsFrom = ActiveWorkbook.Name
Windows(WsTo).Activate
Sheets(1).Select
With ActiveSheet
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
Range("A" & LastRow + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, transpose:=False
Application.CutCopyMode = False
'Save and Close Workbook
Workbooks(WsFrom).Close SaveChanges:=False
'Get next file name
myFile = Dir
Loop
'Message Box when tasks are completed
MsgBox "Importazione completata!"
'Reset Macro Optimization Settings
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
End Sub

Combine Workbooks and Rename imported worksheet using VBA in Excel

I am trying to import all the XLS files in a particular directory into one workbook. I've tried several sources for the code and the closest I've come is the one below (all the rest complained when closing the imported workbook no matter what i tried).
All I want to do now is take the text from a merged cell (C7 and D7) and rename the new worksheet to that. (there is a carriage return above the name in the cell in case this has any impact. I have no control over the source files as they're produced by an external team).
I'm afraid I have almost no ability with coding of any kind but I can normally futz things reading code from other sources but I stumped here. I've managed to get it to rename it to the source filename but I would prefer to get it from the cell text.
Cheers!
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:\Temp\" ' change to suit
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)
ActiveSheet.Name = wsSrc.Range("C7").Value
wbSrc.Close False
strFilename = Dir()
Loop
wbDst.Worksheets(1).Delete
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
I would change this line:
ActiveSheet.Name = wsSrc.Range("C7").Value
to:
wbDst.Worksheets(wbDst.Worksheets.Count).Name = wsSrc.Range("C7")
This will ensure you're naming the sheet in your destination workbook, not in your source workbook, which you might end up with by using ActiveSheet
From your question in the comment about the order of your files:
(BTW - you should edit your post and put the question in there, comments can get deleted)
The order is determined by the "natural" sort order that the files are held in by the OS. I have not found any flags that can be added to the Dir() command to sort them on input.
If you need to process them in name order, I would suggest:
Create a scratch sheet in wbDst
Loop through all the files using Dir(), putting them in Range(A1:An)
i.e put the first file name in Range("A1"), the second file name in Range("A2"), etc
Sort Range(A1:An) so they are in the desired order
Loop through your now sorted Range() to do the actual processing
Delete the scratch sheet from wbDst when you're done processing
For now, comment out:
Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False
These are great things to have in your code, but not until everything is working properly
I would suggest changing:
If Len(strFilename) = 0 Then Exit Sub
to
If Len(strFilename) > 0 Then
Do Until...
Loop
Because, if your initial read of the directory gives you no files, you never get to your clean up code after your loop. At the moment, there's nothing really critical there, but you may modify code in the future, or use this as model for other code that will require critical clean up, and it's a good habit to be in.