Link Value In Unopened/Closed Excel Workbook File - vba

I have list of Excel in same format with different date entry! About 100 excel files, which have different titles. I need to build one master table where I would need to reference some cells from the template used and do some analysis in my master table.
Anyhow, I tried to use the tutorial "How To Reference Or Link Value In Unopened/Closed Excel Workbook File?" to do that and it works fine for closed worksheet!
However, I could not figure way in how to use this tutorial and change the File path dynamically?
Note:
All files in the same folder and every excel sheet have its code and title example: Meal Code-Title.All files have the same structure.
Every Excel have General information in the sheet1, example (Meal Title, Time to prepare,cost, profit, Number of likes, and Number of dislike).The excel sheet have 4 sheets which am not interested on.
I don’t want to merge all files into one file "workbook".I need to have one master excel which do analysis base on the data in the 100 files from Sheet1 (without opening the files).
Here how I did it using index :
=INDEX('D:\Meals[100-Pasta.xlsx]Sheet1'!$B:B,3,1)
Here the formula

Why do the workbooks have to stay closed? You can easily import data from all workbooks in a folder, into a mater file, which contains everything.
Sub Basic_Example_1()
Dim MyPath As String, FilesInPath As String
Dim MyFiles() As String
Dim SourceRcount As Long, Fnum As Long
Dim mybook As Workbook, BaseWks As Worksheet
Dim sourceRange As Range, destrange As Range
Dim rnum As Long, CalcMode As Long
'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
'Add a new workbook with one sheet
Set BaseWks = Workbooks.Add(xlWBATWorksheet).Worksheets(1)
rnum = 1
'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
On Error Resume Next
With mybook.Worksheets(1)
Set sourceRange = .Range("A1:C1")
End With
If Err.Number > 0 Then
Err.Clear
Set sourceRange = Nothing
Else
'if SourceRange use all columns then skip this file
If sourceRange.Columns.Count >= BaseWks.Columns.Count Then
Set sourceRange = Nothing
End If
End If
On Error GoTo 0
If Not sourceRange Is Nothing Then
SourceRcount = sourceRange.Rows.Count
If rnum + SourceRcount >= BaseWks.Rows.Count Then
MsgBox "Sorry there are not enough rows in the sheet"
BaseWks.Columns.AutoFit
mybook.Close savechanges:=False
GoTo ExitTheSub
Else
'Copy the file name in column A
With sourceRange
BaseWks.cells(rnum, "A"). _
Resize(.Rows.Count).Value = MyFiles(Fnum)
End With
'Set the destrange
Set destrange = BaseWks.Range("B" & rnum)
'we copy the values from the sourceRange to the destrange
With sourceRange
Set destrange = destrange. _
Resize(.Rows.Count, .Columns.Count)
End With
destrange.Value = sourceRange.Value
rnum = rnum + SourceRcount
End If
End If
mybook.Close savechanges:=False
End If
Next Fnum
BaseWks.Columns.AutoFit
End If
ExitTheSub:
'Restore ScreenUpdating, Calculation and EnableEvents
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
You may also want to consider using the AddIn from the link below.
https://www.rondebruin.nl/win/addins/rdbmerge.htm

My answer is untested, as am on mobile. It wasn't clear to me whether you had an existing list of the 100 Excel files, with codes and meals for each one, somewhere (your Master Table image shows only one row/file) -- or whether you wanted to look up all the files.
Code below attempts to look up the files.
Option Explicit
Sub InsertExternalReferences()
' Change if/as needed to the folder of the 100 Excel files. '
Const FOLDER_PATH as string = "D:\Meals"
Dim Filename as string
Filename = dir$(folder_path &"\*-*.xlsx" , vbnormal)
Dim Index as long
Dim FileIndex as long
' Change this line to the name of the sheet that contains the MasterTable -- else you'll get an error. '
With thisworkbook.worksheets("MasterTable")
Do until Len(filename) = 0
FileIndex = FileIndex + 1
' To me, does not make sense to use the INDEX function. It would make sense if you were looking up the value dynamically with a combination of INDEX and MATCH, but you do not appear to be. You may as well just give the cell reference if structure throughout 100 workbooks is not going to change. '
' Reading rows 2 to 8 on each Sheet1'
For Index = 2 to 8
'Index+2 below means we start writing from column 4 (AKA column D).'
'5+ below means we are skipping the first 5 rows on the MasterTable sheet and begin writing from the sixth row. Change it to however many rows you need to skip.'
.cells(5+FileIndex,Index+2).formula = "='" & folder_path & "[" & filename & "]Sheet1'!B" & cstr(Index)
Next index
Filename = dir$()
Loop
End with
End sub
If I have misunderstood, let me know.

Related

Merging multiple workbooks into single sheet in current workbook

I need VBA code to select multiple workbooks by browsing the files and then merge all those into 1 sheet of current workbook.
All multiple workbooks having only 1 sheet
headers is same for all workbooks so header is constant
Merging should not get any empty rows while filling workbook by workbook
No repetition of headers when merging.
When 1st workbook merging is done, 2nd workbook data should be merged in the same sheet of current workbook exactly next row of the merged 1st workbook data ends which means no empty rows or gaps
First, This will not paste any headers. Since they are all the same, just move the headers to the excel that will store the consolidation. (No need for a macro to do this since it only needs to happen once).
Second, in the code you need to change "SHEETNAME?" to the name of the sheet on your main book that will store the consolidation. (2 instances, do not remove quotes)
Third, I am assuming there is no blanks in Column A which is what determines how far down to copy. If you expect blanks in Column A, this needs to be amended to reflect a column that is least likely to have blanks.
Lastly, I am copying from Column A to Z. Change the "Z" to the last column in your file that contains data.
Given the quality of (or lack of) your question, this is more than you bargained for :)
Happy Editing.
Option Explicit
Sub Consolidation()
Dim CurrentBook As Workbook
Dim WS As Worksheet
Set WS = ThisWorkbook.Sheets("SHEETNAME?")
Dim IndvFiles As FileDialog
Dim FileIdx As Long
Dim i As Integer, x As Integer
Set IndvFiles = Application.FileDialog(msoFileDialogOpen)
With IndvFiles
.AllowMultiSelect = True
.Title = "Multi-select target data files:"
.ButtonName = ""
.Filters.Clear
.Filters.Add ".xlsx files", "*.xlsx"
.Show
End With
Application.DisplayAlerts = False
Application.ScreenUpdating = False
For FileIdx = 1 To IndvFiles.SelectedItems.Count
Set CurrentBook = Workbooks.Open(IndvFiles.SelectedItems(FileIdx))
For Each Sheet In CurrentBook.Sheets
Dim LRow1 As Long
LRow1 = WS.Range("A" & WS.Rows.Count).End(xlUp).Row
Dim LRow2 As Long
LRow2 = CurrentBook.ActiveSheet.Range("A" & CurrentBook.ActiveSheet.Rows.Count).End(xlUp).Row
Dim ImportRange As Range
Set ImportRange = CurrentBook.ActiveSheet.Range("A2:Z" & LRow2)
ImportRange.Copy
WS.Range("A" & LRow1 + 1).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Next
CurrentBook.Close False
Next FileIdx
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
How about this option? Modify to suit your needs.
Sub Basic_Example_1()
Dim MyPath As String, FilesInPath As String
Dim MyFiles() As String
Dim SourceRcount As Long, Fnum As Long
Dim mybook As Workbook, BaseWks As Worksheet
Dim sourceRange As Range, destrange As Range
Dim rnum As Long, CalcMode As Long
'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
'Add a new workbook with one sheet
Set BaseWks = Workbooks.Add(xlWBATWorksheet).Worksheets(1)
rnum = 1
'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
On Error Resume Next
With mybook.Worksheets(1)
Set sourceRange = .Range("A1:C1")
End With
If Err.Number > 0 Then
Err.Clear
Set sourceRange = Nothing
Else
'if SourceRange use all columns then skip this file
If sourceRange.Columns.Count >= BaseWks.Columns.Count Then
Set sourceRange = Nothing
End If
End If
On Error GoTo 0
If Not sourceRange Is Nothing Then
SourceRcount = sourceRange.Rows.Count
If rnum + SourceRcount >= BaseWks.Rows.Count Then
MsgBox "Sorry there are not enough rows in the sheet"
BaseWks.Columns.AutoFit
mybook.Close savechanges:=False
GoTo ExitTheSub
Else
'Copy the file name in column A
With sourceRange
BaseWks.cells(rnum, "A"). _
Resize(.Rows.Count).Value = MyFiles(Fnum)
End With
'Set the destrange
Set destrange = BaseWks.Range("B" & rnum)
'we copy the values from the sourceRange to the destrange
With sourceRange
Set destrange = destrange. _
Resize(.Rows.Count, .Columns.Count)
End With
destrange.Value = sourceRange.Value
rnum = rnum + SourceRcount
End If
End If
mybook.Close savechanges:=False
End If
Next Fnum
BaseWks.Columns.AutoFit
End If
ExitTheSub:
'Restore ScreenUpdating, Calculation and EnableEvents
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
https://www.rondebruin.nl/win/s3/win008.htm

Sub procedure for importing the sheets it's substandar

I get this code to work for a time but the last couple of days it has not been working. from active workbook1 its suppose to import the sheets to Thisworkbook2:
Sub ImportallWBsh()
'https://michaelaustinfu.files.wordpress.com/2013/03/excel-vba-for-dummies-3rd-edition.pdf, Page 245
Dim Finfo As String
Dim FilterIndex As Integer
Dim Title As String
Dim Filename As Variant
Dim wb As Workbook
'Setup the list of file filters
Finfo = "Excel Files (*.xlsx),*xlsx,"
'Display *.* by default
FilterIndex = 1
'Set the dialog box caption
Title = "Select a File to Import"
'Get the Filename
Filename = Application.GetOpenFilename(Finfo, _
FilterIndex, Title)
'Handle return info from dialog box
If Filename = False Then
MsgBox "No file was selected."
Else
MsgBox "You selected " & Filename
End If
On Error Resume Next
Set wb = Workbooks.Open(Filename)
FilenameWorkbook.Sheets.Copy _
After:=ThisWorkbook.Sheets("Sheet3")
wb.Close True
ThisWorkbook.Sheets("Sheet1").Select
End Sub
Do you know what might be wrong about it.
Thank you
You've got a couple issues going on...
You are using Set incorrectly. GetOpenFileName returns a string. Workbooks.Open returns an object. Check this out. The first section of your could read:
s = Application.GetOpenFilename()
Set Wb1 = Workbooks.Open (s)
You're also opening workbook s twice, plus you create object objexcel which creates a new instance of Excel, but you don't close it with Set objexcel = Nothing, so each time you run the code, you'll have another copy of Excel open in the background.
(Close Excel, then CTRL+ALT+DEL to check your Task Manager and I bet you'll see what I mean!)
To start with I suggest you try this search, which will show a number of solutions to the same question that have worked for others, such as this and this.
Something like this should do the job for you.
Sub Basic_Example_1()
Dim MyPath As String, FilesInPath As String
Dim MyFiles() As String
Dim SourceRcount As Long, Fnum As Long
Dim mybook As Workbook, BaseWks As Worksheet
Dim sourceRange As Range, destrange As Range
Dim rnum As Long, CalcMode As Long
'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
'Add a new workbook with one sheet
Set BaseWks = Workbooks.Add(xlWBATWorksheet).Worksheets(1)
rnum = 1
'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
On Error Resume Next
With mybook.Worksheets(1)
Set sourceRange = .Range("A1:C1")
End With
If Err.Number > 0 Then
Err.Clear
Set sourceRange = Nothing
Else
'if SourceRange use all columns then skip this file
If sourceRange.Columns.Count >= BaseWks.Columns.Count Then
Set sourceRange = Nothing
End If
End If
On Error GoTo 0
If Not sourceRange Is Nothing Then
SourceRcount = sourceRange.Rows.Count
If rnum + SourceRcount >= BaseWks.Rows.Count Then
MsgBox "Sorry there are not enough rows in the sheet"
BaseWks.Columns.AutoFit
mybook.Close savechanges:=False
GoTo ExitTheSub
Else
'Copy the file name in column A
With sourceRange
BaseWks.cells(rnum, "A"). _
Resize(.Rows.Count).Value = MyFiles(Fnum)
End With
'Set the destrange
Set destrange = BaseWks.Range("B" & rnum)
'we copy the values from the sourceRange to the destrange
With sourceRange
Set destrange = destrange. _
Resize(.Rows.Count, .Columns.Count)
End With
destrange.Value = sourceRange.Value
rnum = rnum + SourceRcount
End If
End If
mybook.Close savechanges:=False
End If
Next Fnum
BaseWks.Columns.AutoFit
End If
ExitTheSub:
'Restore ScreenUpdating, Calculation and EnableEvents
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
https://www.rondebruin.nl/win/s3/win008.htm
The correct line code needs to be:
ActiveWorkbook.Sheets.Copy _
After:=ThisWorkbook.Sheets("Hoja3")
So the code work properly. Thank you

Error selecting range cells to copy from multiple work books

Updated in response to comment from dwirony:
I am trying to create a code that copies information from the same cells in multiple workbooks and combines the information into a single summary workbook. The code below works as written, however, if I add more cell address to the sourceRange (starting on line 69) the macro still runs but no information is copied into the new summary workbook.
Original Question:
I am trying to select the same specific cells from multiple worksheets within a single folder and combine them into a master spreadsheet. The code works up to a certain number of cells, but if I try to include any more, the macro returns a blank workbook (except for the column headings I've assigned). Cells that work initially will won't work if there are too many selected cells. i.e., in the code shown below, cell J2 is the first and the last cell called and the program runs. If I add J2 again, (range ends ...J2, J2")or any other cell, it appears that I've hit a limit somewhere and I get a blank workbook.
I have zero previous experience with VBA and macros, and everything I've put together comes from a variety of internet and internal sources. Maybe the multiple sources are the source of the error?
Any help would be greatly appreciated!
Sub MergeAllWorkbooks()
Dim MyPath As String, FilesInPath As String
Dim MyFiles() As String
Dim SourceRcount As Long, FNum As Long
Dim mybook As Workbook, BaseWks As Worksheet
Dim sourceRange As Range, destrange As Range
Dim rnum As Long, CalcMode As Long
Dim a As Range, c As Range
Dim x As Long
' Change this to the path\folder location of your files.
MyPath = "C:\Users\amiller\OneDrive - CoorsTek\temp"
' Add a slash at the end of the path if needed.
If Right(MyPath, 1) <> "\" Then
MyPath = MyPath & "\"
End If
' If there are no Excel files in the folder, exit.
FilesInPath = Dir(MyPath & "*.xls*")
If FilesInPath = "" Then
MsgBox "No files found"
Exit Sub
End If
' Fill the myFiles array with the list of Excel files
' in the search folder.
FNum = 0
Do While FilesInPath <> ""
FNum = FNum + 1
ReDim Preserve MyFiles(1 To FNum)
MyFiles(FNum) = FilesInPath
FilesInPath = Dir()
Loop
' Set various application properties.
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
End With
' Add a new workbook with one sheet.
Set BaseWks = Workbooks.Add(xlWBATWorksheet).Worksheets(1)
rnum = 1
' Loop through all files in the myFiles array.
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
On Error Resume Next
' Change this range to fit your own needs.
With mybook.Worksheets(1)
Set sourceRange = .Range("J2, C2, D7, F7, K7, G10, J10, G11, J11, G12, J12, G14, J14, G15, J15, G16, J16, G17, J17, J21," _
& "J2, D24, E24, G24, I24, J24, O24, P24, Q24, R24, S24, D25, E25, G25, I25, J25, O25, P25, Q25, R25, S25," _
& "D26, E26, G26, I26, J26, O26, P26, Q26, R26, S26, D27, J2")
End With
If Err.Number > 0 Then
Err.Clear
Set sourceRange = Nothing
Else
' If source range uses all columns then
' skip this file.
If sourceRange.Columns.Count >= BaseWks.Columns.Count Then
Set sourceRange = Nothing
End If
End If
On Error GoTo 0
If Not sourceRange Is Nothing Then
SourceRcount = sourceRange.Rows.Count
If rnum + SourceRcount >= BaseWks.Rows.Count Then
MsgBox "There are not enough rows in the target worksheet."
BaseWks.Columns.AutoFit
mybook.Close savechanges:=False
GoTo ExitTheSub
Else
' Copy the file name in column A.
With sourceRange
BaseWks.Cells(rnum + 1, "A"). _
Resize(.Rows.Count).Value = MyFiles(FNum)
End With
' Set the destination range.
Set destrange = BaseWks.Range("B" & rnum + 1)
x = 0
For Each a In sourceRange.Areas
For Each c In a.Cells
x = x + 1
destrange.Offset(0, x - 1).Value = c.Value
Next c
Next a
' Copy the values from the source range
' to the destination range.
With sourceRange
Set destrange = destrange. _
Resize(.Rows.Count, .Columns.Count)
End With
destrange.Value = sourceRange.Value
rnum = rnum + SourceRcount
End If
End If
mybook.Close savechanges:=False
End If
Next FNum
BaseWks.Columns.AutoFit
End If
ExitTheSub:
' Restore the application properties.
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub

VBA to Import Excel data from from sub-Folders too - Consolidated Excel File

It's my first in using VBA, excuse my rustiness.
My Situation: I have a master excel (2010) file to which I need to import excel files from a folder. The existing code works almost fine but does not look into the sub-folders. Along with below important requirements. Please help!
Desired Output:
The code should not create a new excel sheet, instead import the data into the same master excel file that the code sits in.
Currently, the code fetches excel files only from the parent folder. I need it to look into any sub-folders with excel files in them too
The current code changes the destination files format, I would like to keep the destination format as is.
Should not copy empty rows from the defined range
Existing code (From MSDN: Ron de Bruin)
Sub MergeAllWorkbooks()
Dim MyPath As String, FilesInPath As String
Dim MyFiles() As String
Dim SourceRcount As Long, FNum As Long
Dim mybook As Workbook, BaseWks As Worksheet
Dim sourceRange As Range, destrange As Range
Dim rnum As Long, CalcMode As Long
' Change this to the path\folder location of your files.
MyPath = "C:\Users\zatin.dharmapuri\Desktop\Reviews"
' Add a slash at the end of the path if needed.
If Right(MyPath, 1) <> "\" Then
MyPath = MyPath & "\"
End If
' If there are no Excel files in the folder, exit.
FilesInPath = Dir(MyPath & "*.xl*")
If FilesInPath = "" Then
MsgBox "No files found"
Exit Sub
End If
' Fill the myFiles array with the list of Excel files
' in the search folder.
FNum = 0
Do While FilesInPath <> ""
FNum = FNum + 1
ReDim Preserve MyFiles(1 To FNum)
MyFiles(FNum) = FilesInPath
FilesInPath = Dir()
Loop
' Set various application properties.
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
End With
' Add a new workbook with one sheet.
Set BaseWks = Workbooks.Add(xlWBATWorksheet).Worksheets(1)
rnum = 1
' Loop through all files in the myFiles array.
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
On Error Resume Next
' Change this range to fit your own needs.
With mybook.Worksheets(1)
Set sourceRange = .Range("B2:G50")
End With
If Err.Number > 0 Then
Err.Clear
Set sourceRange = Nothing
Else
' If source range uses all columns then
' skip this file.
If sourceRange.Columns.Count >= BaseWks.Columns.Count Then
Set sourceRange = Nothing
End If
End If
On Error GoTo 0
If Not sourceRange Is Nothing Then
SourceRcount = sourceRange.Rows.Count
If rnum + SourceRcount >= BaseWks.Rows.Count Then
MsgBox "There are not enough rows in the target worksheet."
BaseWks.Columns.AutoFit
mybook.Close savechanges:=False
GoTo ExitTheSub
Else
' Copy the file name.
With sourceRange
BaseWks.Cells(rnum, "L"). _
Resize(.Rows.Count).Value = MyFiles(FNum)
End With
' Set the destination range.
Set destrange = BaseWks.Range("A" & rnum)
' Copy the values from the source range
' to the destination range.
With sourceRange
Set destrange = destrange. _
Resize(.Rows.Count, .Columns.Count)
End With
destrange.Value = sourceRange.Value
rnum = rnum + SourceRcount
End If
End If
mybook.Close savechanges:=False
End If
Next FNum
BaseWks.Columns.AutoFit
End If
ExitTheSub:
' Restore the application properties.
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
There are several ways to do this. Probably the easiest is to use Ron deBruin's AddIn.
http://www.rondebruin.nl/win/addins/rdbmerge.htm
Check the box that says 'Include Sub Folders'.

How to append data to existing workbook's sheet and don't create a new workbook

I am trying to work out what I need to change in the following VBA code to append the data at the bottom of data that already exists in a workbook named "Main" and a worksheet named "summary":
Sub MergeAllWorkbooks()
Dim MyPath As String, FilesInPath As String
Dim MyFiles() As String
Dim SourceRcount As Long, FNum As Long
Dim mybook As Workbook, BaseWks As Worksheet
Dim sourceRange As Range, destrange As Range
Dim rnum As Long, CalcMode As Long
' Change this to the path\folder location of your files.
MyPath = "C:\test\"
' Add a slash at the end of the path if needed.
If Right(MyPath, 1) <> "\" Then
MyPath = MyPath & "\"
End If
' If there are no Excel files in the folder, exit.
FilesInPath = Dir(MyPath & "*.xl*")
If FilesInPath = "" Then
MsgBox "No files found"
Exit Sub
End If
' Fill the myFiles array with the list of Excel files
' in the search folder.
FNum = 0
Do While FilesInPath <> ""
FNum = FNum + 1
ReDim Preserve MyFiles(1 To FNum)
MyFiles(FNum) = FilesInPath
FilesInPath = Dir()
Loop
FNum = FNum - 1
' Set various application properties.
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
End With
' Add a new workbook with one sheet.
Set BaseWks = Workbooks.Add(xlWBATWorksheet).Worksheets(1)
rnum = 1
' Loop through all files in the myFiles array.
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
On Error Resume Next
' Change this range to fit your own needs.
With mybook.Worksheets(1)
Set sourceRange = .Range("A2:T" & CStr(mybook.Worksheets(1).Range("A2").CurrentRegion.Rows.Count))
End With
If Err.Number > 0 Then
Err.Clear
Set sourceRange = Nothing
Else
' If source range uses all columns then
' skip this file.
If sourceRange.Columns.Count >= BaseWks.Columns.Count Then
Set sourceRange = Nothing
End If
End If
On Error GoTo 0
If Not sourceRange Is Nothing Then
SourceRcount = sourceRange.Rows.Count
If rnum + SourceRcount >= BaseWks.Rows.Count Then
MsgBox "There are not enough rows in the target worksheet."
BaseWks.Columns.AutoFit
mybook.Close savechanges:=False
GoTo ExitTheSub
Else
' Copy the file name in column A.
With sourceRange
BaseWks.Cells(rnum, "A"). _
Resize(.Rows.Count).Value = MyFiles(FNum)
End With
' Set the destination range.
Set destrange = BaseWks.Range("B" & rnum)
' Copy the values from the source range
' to the destination range.
With sourceRange
Set destrange = destrange. _
Resize(.Rows.Count, .Columns.Count)
End With
destrange.Value = sourceRange.Value
rnum = rnum + SourceRcount
End If
End If
mybook.Close savechanges:=False
End If
Next FNum
BaseWks.Columns.AutoFit
End If
ExitTheSub:
' Restore the application properties.
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
Thank you
I do not like this code. There is lots I object to but I am most unhappy about the use of error handling:
The error handling functionality is there to allow your routine to fail gracefully when something goes wrong. It is not there to allow you to ignore errors and carry on as though they did not happen.
The error handling failed to handle a problem with one of my workbooks. I have not investigated but I suspect the problem is either the length of a single cell or the total length of the data being transferred by destrange.Value = sourceRange.Value.
However, you ask how to make a single change so I will limit myself to that.
I suggest the easiest approach would be to create workbook "Main" with worksheet "Summary" and to include your macro in it.
Add new statements under the Dim statements:
Dim rnum As Long, CalcMode As Long
'### Start of new code
If Workbooks.Count > 1 Then
' It is easy to get into a muddle if there are multiple workbooks
' open at the start of a macro like this. Avoid the problem until
' you understand it.
Call MsgBox("Please close all other workbooks", vbOKOnly)
Exit Sub
End If
Set BaseWks = ActiveWorkBook.Worksheets("Summary")
With BaseWks
rnum = .Cells(Rows.Count, "A").End(xlUp).Row + 1
End With
'### End of new code
' Change this to the path\folder location of your files.
The first block of the above code ensures there are no other workbooks open.
The second block (1) sets BaseWks to worksheet "Summary" and (2) sets rnum to the first unused row in "Summary". End(xlUp) is the VBA equivalent of clicking Ctrl+Up. So I have gone to the bottom of column A, gone up until I hit a row with a value and then down 1 row.
Replace the loop that locates the filenames with:
Do While FilesInPath <> ""
If FilesInPath <> ActiveWorkbook.Name Then
FNum = FNum + 1
ReDim Preserve MyFiles(1 To FNum)
MyFiles(FNum) = FilesInPath
End If
FilesInPath = Dir()
Loop
I assume that workbook "Main" will be in the same folder as the other workbooks. This change ensures that "Main" is not used as a source.
Discard these statements:
Set BaseWks = Workbooks.Add(xlWBATWorksheet).Worksheets(1)
rnum = 1
because I have already set BaseWks and rnum to the values I require.
If you want to save the updated workbook "Main" automatically, add the following statement above ExitTheSub::
ActiveWorkbook.Save