First of all, some thoughts on improving the coding style.
You should avoid using Selection , Select and Activate because it is bad practice and slows down your code significantly. You can do all the actions without using them. In most cases, you should never use them (there are very few special cases).
Do not use, for example. Range or Cells without specifying a worksheet. Otherwise, Excel is trying to guess which worksheet you have in mind, and it probably won't work. Guessing does not know, therefore it always tells Excel which worksheet you mean as Worksheets(1).Range or Worksheets("SheetName").Range .
Use descriptive variable names. Names like wbk and wbk1 are not very descriptive, and later you don't know what wbk1 , and you messed it up. Instead, use something like wbDestination and wbSource , everyone knows what that means now. It may also be good practice to declare variables close to their first use, especially when the code gets a little longer.
Always use Worksheets instead of Sheets , if possible. Sheets also contains diagrams not only of books, but in most cases you just need Worksheets . You say it doesn't matter? Good. Sheets(1).Range will Sheets(1).Range error if the first sheet is a chart. We can avoid this.
Now let's start cleaning ...
Instead of activating, select 3 times and copy
wbk.Activate Range("A2").Select Range(Selection, Selection.End(xlToRight)).Select Range(Selection, Selection.End(xlDown)).Select Selection.Copy
We can simply copy without any attack or choice, which is much faster and has the same effect:
With wbSource.Worksheets(1).Range("A2") 'copy without select .Resize(.End(xlDown).Row - .Row + 1, .End(xlToRight).Column - .Column + 1).Copy End With
When we close the source book
wbSource.Close SaveChanges:=False
we do not need to save changes because we have not changed anything. It is safer and much faster.
So we are done with
Option Explicit Sub MergeDataFromWorkbooks() Dim wbDestination As Workbook Set wbDestination = ThisWorkbook Dim Path As String Path = "C:\Temp\" 'make sure it ends with \ Dim Filename As String Filename = Dir(Path & "*.xlsx") Do While Len(Filename) > 0 'while file exists Dim wbSource As Workbook Set wbSource = Workbooks.Open(Path & Filename) With wbSource.Worksheets(1).Range("A2") 'copy without select .Resize(.End(xlDown).Row - .Row + 1, .End(xlToRight).Column - .Column + 1).Copy End With Dim lRow As Double lRow = wbDestination.Worksheets(1).Cells(Rows.Count, 1).End(xlUp).Row 'find next empty row wbDestination.Worksheets(1).Cells(lRow + 1, 1).PasteSpecial Paste:=xlPasteAll 'paste all wbSource.Close SaveChanges:=False 'we don't need to save changes we didn't change anything just copied Filename = Dir 'next file Loop MsgBox "All the files are copied and pasted in Book1." End Sub
An alternative way to determine the last used cell (column and row) in the source file
This avoids errors when line 2 is the last line used.
With wbSource.Worksheets(1).Range("A2") .Resize(.Parent.Cells(.Parent.Rows.Count, .Column).End(xlUp).Row - .Row + 1, .Parent.Cells(.Row, .Parent.Columns.Count).End(xlToLeft).Column - .Column + 1).Copy End With
Explanation:
.Parent.Cells(.Parent.Rows.Count, .Column).End(xlUp).Row
finds the last row used in column A, starting from the very last cell in Excel and rising (for example, by pressing ctrl + up ).