Looping through files in a folder, copy contents to specific sheet and loop through sheets in master file - vba

Before starting to explain my problem, sorry for the messy code, I'm still a beginner in VBA and thank you for your help in advance.
So what I'm trying to do is getting a way of copying the contents of some workbooks in a folder to my master file, which is kinda like a data base. The trick here is that I need the 2 sheets from the file to be copied into the 1st sheet of my master file.
In the mean time and looking through a lot of posts, like this one,
VBA Loop through files in folder and copy/paste to master file, I came up with this code:
Option Explicit
Sub AllFiles()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.EnableEvents = False
Application.EnableCancelKey = xlDisabled
Application.ScreenUpdating = False
Dim folderPath As String
Dim Filename As String
Dim wb As Workbook
Dim Masterwb As Workbook
Dim sh As Worksheet
Dim NewSht As Worksheet
Dim FindRng As Range
Dim PasteRow As Long
Dim i As Integer
' set master workbook
Set Masterwb = ThisWorkbook
folderPath = Sheets("teste").Range("A1").Value 'contains folder path
If Right(folderPath, 1) <> "\" Then folderPath = folderPath & "\"
For i = 1 To Sheets("leit_func").Range("S2")
Filename = Dir(folderPath & Sheets("teste").Range("A3"))
Do While Filename <> ""
Set wb = Workbooks.Open(folderPath & Filename)
If Len(wb.Name) > 35 Then
MsgBox "Sheet's name can be up to 31 characters long, shorten the Excel file name"
wb.Close False
GoTo Exit_Loop
Else
' add a new sheet with the file's name (remove the extension)
'-------------------------------------------------------------------------------------------
'Set NewSht = Masterwb.Worksheets.Add(After:=Masterwb.Worksheets(1))
'NewSht.Name = Replace(wb.Name, ".xlsx", "")
'-------------------------------------------------------------------------------------------
Set NewSht = ThisWorkbook.Sheets(i)
End If
' loop through all sheets in opened wb
For Each sh In wb.Worksheets
' get the first empty row in the new sheet
Set FindRng = NewSht.Cells.Find(What:="*", Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False)
If Not FindRng Is Nothing Then ' If find is successful
PasteRow = FindRng.Row + 1
Else ' find was unsuccessfull > new empty sheet, should paste at the first row
PasteRow = 1
End If
sh.UsedRange.Copy
NewSht.Range("A" & PasteRow).PasteSpecial xlPasteValues
'NewSht.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
Next sh
wb.Close False
Exit_Loop:
Set wb = Nothing
Filename = Dir()
Loop
Next i
Application.ScreenUpdating = True
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.EnableEvents = False
End Sub
With this code I can paste the info in different sheets, but the problem is that it's getting the contents from all the files in the folder, and I want file 1 in sheet 1, file 2 in sheet 2, and so on.
I think my problem has something to do with the placement of my For cycle for the sheets, but I'm not exactly sure.
Thank you!

Here is a copy/paste from a script library i keep. It is a rough example of how to loop through files in a directory and copy and paste each sheet to a new sheet in the master workbook. I have included a section that shows how to append to the end of a range as well. Both can be useful. Note that i use arrays to move data as its easier and faster.
Public Sub this()
Dim path As String, fileName As String, shtName As String
Dim sheet As Worksheet, thisWB As Workbook, thatWB As Workbook
Dim arr() As Variant
Dim rowC As Long, colC As Long, mrowC As Long, mColC As Long
path = "your path to directory" & "\"
fileName = Dir(path & "*.xl??")
Set thisWB = ThisWorkbook
Do While Len(fileName) > 0
Set thatWB = Workbooks.Open(path & fileName, True, True)
For Each sheet In thatWB.Sheets
shtName = Left(Mid(fileName, 1, InStrRev(fileName, ".") - 1), 30)
thisWB.ActiveSheet.Name = shtName
mrowC = thisWB.Sheets(shtName).UsedRange.Rows.Count
mColC = thisWB.Sheets(shtName).UsedRange.Columns.Count
arr = sheet.UsedRange
rowC = sheet.UsedRange.Rows.Count
colC = sheet.UsedRange.Columns.Count
thisWB.Sheets(shtName).Range(thisWB.Sheets(shtName).Cells(mrowC + 1, 1), thisWB.Sheets(shtName).Cells(mrowC + 1 + rowC, colC)).Value2 = arr
Next sheet
thatWB.Close False
fileName = Dir()
thisWB.Sheets.Add After:=Worksheets(Worksheets.Count)
Loop
End Sub

Related

Loop inserting worksheet name in column - mismatch error

Trying to do the following
1- Open directory with multiple workbooks (Origins), copy/paste
each worksheet into Master workbook (Destin)
2- insert in Columns 'A' in Master worksheet (Destin) with the name of each worksheet from dir (Origin) - the worksheets name contain the date
3- Finally, consolidate all worksheets in Master workbook (Destin) into 'Summary' sheet by copy/paste each
worksheet below the other (i.e. database format)
got step-1 to work....stuck now (step-2 mismatch error)
Option Explicit
Sub AllFiles()
'Application.EnableCancelKey = xlDisabled
Application.DisplayAlerts = True
Application.ScreenUpdating = False
Dim folderPath As String
Dim Filename As String
Dim wb As Workbook
Dim Masterwb As Workbook
Dim sh As Worksheet
Dim NewSht As Worksheet
Dim FindRng As Range
Dim PasteRow As Long
Dim lastrow As Long
' set master workbook
Set Masterwb = Workbooks("masterbook_AAFC.xlsm")
folderPath = "C:\Users\axchilmeran.G3NETWORK\Downloads\Master_AAFC\" 'contains folder path
If Right(folderPath, 1) <> "\" Then folderPath = folderPath & "\"
Filename = Dir(folderPath & "*.csv*")
Do While Filename <> ""
Set wb = Workbooks.Open(folderPath & Filename)
If Len(wb.Name) > 35 Then
MsgBox "Sheet's name can be up to 31 characters long, shorten the Excel file name"
wb.Close False
GoTo Exit_Loop
Else
' add a new sheet with the file's name (remove the extension)
Set NewSht = Masterwb.Worksheets.Add(After:=Masterwb.Worksheets(1))
NewSht.Name = Replace(wb.Name, ".pdf.csv", "")
End If
' loop through all sheets in opened wb
For Each sh In wb.Worksheets
' get the first empty row in the new sheet
Set FindRng = NewSht.Cells.Find(What:="*", Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False)
If Not FindRng Is Nothing Then ' If find is successful
PasteRow = FindRng.Row + 1
Else ' find was unsuccessfull > new empty sheet, should paste at the first row
PasteRow = 1
End If
sh.UsedRange.Copy
NewSht.Range("B" & PasteRow).PasteSpecial xlPasteValues
these 2 lines below giving me mismatch error!
**lastrow = NewSht.UsedRange.Rows(NewSht.UsedRange.Rows.Count).Row
Worksheets(NewSht).Range("A2:A" & lastrow).Value = NewSht.Name**
Next sh
wb.Application.CutCopyMode = False
wb.Close False
Exit_Loop:
Set wb = Nothing
Filename = Dir
Loop
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub

Trying to copy static cell value from workbook A and paste into dynamic location in workbook B

I'm trying to:
Copy cell "B2:C2" from every workbook in a folder from the "Results" worksheet.
Paste the value into Cell A1:A2 Sheet1 in workbook "x"in the same folder.
I think I know how to open and do something to every workbook within a folder.
Option Explicit
Sub LoopThroughDirectory()
Dim MyFile As String
Dim WorkbookCounter As Long
WorkbookCounter = 1
Dim Filepath As String
Dim wb As Workbook
Dim RowCounter As Long
RowCounter = 1
Filepath = "C:\Test\"
Application.ScreenUpdating = False
MyFile = Dir(Filepath)
'Opens workbooks located C:\Test\ in order
Do While Len(MyFile) > 0
Set wb = Workbooks.Open(Filepath & MyFile)
Application.DisplayAlerts = False
'Copy cells B2 & C2 from the results worksheet
ThisWorkbook.Worksheets("x").Range(Cells(RowCounter, 1), Cells(RowCounter, 2)).Value = _
wb.Worksheets("Results").Range("B2:C2").Value
'Close wb most recently opened
wb.Close SaveChanges:=False
Application.CutCopyMode = False
WorkbookCounter = WorkbookCounter + 1
If WorkbookCounter > 1000 Then
Exit Sub
End If
MyFile = Dir
RowCounter = RowCounter + 1
Loop
ActiveWorkbook.Save
Application.ScreenUpdating = True
End Sub
Update: With help in the comments below the above code now correctly loops through the correct folder and updates cell A1:A2.
Instead of overwriting cell A1:A2 I'd like to paste the copied text one line down.
i.e. Workbook 1 = A1:A2, Workbook 2 = B1:B2, etc
I don't see any check to make sure you are not trying to open ThisWorkbook and there is no check to see if there is a Results worksheet in the source workbook; in fact there is no check to ensure that you are trying to open a workbook at all, you could be trying to open a JPG.
Further error control could be added to ensure that you are not trying to open another workbook that is already open. I suspect that after all the testing, you might have a few.
Option Explicit
Sub LoopThroughDirectory()
Dim myFile As String, filepath As String
Dim wbc As Long, ws As Worksheet, wb As Workbook
wbc = 0
filepath = "C:\Test\"
'Application.ScreenUpdating = False
'only try to open workbooks
myFile = Dir(filepath & "*.xls*")
'Opens workbooks located C:\Test\ in order
Do While Len(myFile) > 0
'make sure myFile isn't ThisWorkbook
If Split(myFile & ".", ".")(0) <> Split(ThisWorkbook.Name & ".", ".")(0) Then
Set wb = Workbooks.Open(Filename:=filepath & myFile, ReadOnly:=True)
'Application.DisplayAlerts = False
'check if there is a Results worksheet
On Error Resume Next
Set ws = wb.Worksheets("Results")
On Error GoTo 0
If Not ws Is Nothing Then
'transfer cells B2 & C2 from the results worksheet
With ws.Range("B2:C2")
ThisWorkbook.Worksheets("x").Range("A1").Offset(wbc, 0).Resize(.Rows.Count, .Columns.Count) = .Value
End With
End If
'Close wb most recently opened
wb.Close SaveChanges:=False
wbc = wbc + 1
If wbc > 1000 Then Exit Do
End If
Set ws = Nothing
myFile = Dir
Loop
ActiveWorkbook.Save
'Application.ScreenUpdating = True
End Sub

Combining Excel workbooks, but need the all worksheets, not just the first

I found this VBA code that works for combining workbooks in a folder, however, I need to modify it so that all worksheets in each workbook are copy/pasted and not just the first worksheet of each workbook. As of now, only the first worksheet in each selected workbook is being copied over. Where can I insert code to find data in all worksheets?
Thanks!
Sub MergeSelectedWorkbooks()
Dim SummarySheet As Worksheet
Dim FolderPath As String
Dim SelectedFiles() As Variant
Dim NRow As Long
Dim FileName As String
Dim NFile As Long
Dim WorkBk As Workbook
Dim SourceRange As Range
Dim DestRange As Range
' Create a new workbook and set a variable to the first sheet.
Set SummarySheet = Workbooks.Add(xlWBATWorksheet).Worksheets(1)
' Modify this folder path to point to the files you want to use.
FolderPath = "S:\example"
' Set the current directory to the the folder path.
ChDrive FolderPath
ChDir FolderPath
' Open the file dialog box and filter on Excel files, allowing multiple files
' to be selected.
SelectedFiles = Application.GetOpenFilename( _
filefilter:="Excel Files (*.xl*), *.xl*", MultiSelect:=True)
' NRow keeps track of where to insert new rows in the destination workbook.
NRow = 1
' Loop through the list of returned file names
For NFile = LBound(SelectedFiles) To UBound(SelectedFiles)
' Set FileName to be the current workbook file name to open.
FileName = SelectedFiles(NFile)
' Open the current workbook.
Set WorkBk = Workbooks.Open(FileName)
Dim LastRow As Long
LastRow = WorkBk.Worksheets(1).Cells.Find(What:="*", _
After:=WorkBk.Worksheets(1).Cells.Range("A1"), _
SearchDirection:=xlPrevious, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows).Row
Set SourceRange = WorkBk.Worksheets(1).Range("A1:Z" & LastRow)
' Set the destination range to start at column A and be the same size as the source range.
Set DestRange = SummarySheet.Range("A" & NRow)
Set DestRange = DestRange.Resize(SourceRange.Rows.Count, _
SourceRange.Columns.Count)
' Copy over the values from the source to the destination.
DestRange.Value = SourceRange.Value
' Increase NRow so that we know where to copy data next.
NRow = NRow + DestRange.Rows.Count
' Close the source workbook without saving changes.
WorkBk.Close savechanges:=False
Next NFile
' Call AutoFit on the destination sheet so that all data is readable.
SummarySheet.Columns.AutoFit
End Sub
Opens multiple workbooks (1 by 1), Copies data from all sheets onto one sheet. Make sure you modify the ranges that will work for you (copy range is currently A2 to Z(last row).
Option Explicit
Sub MoveSheets()
Dim IndvFiles As FileDialog
Dim Currentbook As Workbook
Dim x As Integer
Dim i As Integer
Dim CurrentSheets As Integer
Dim BookCount As Integer
'Opens File Dialog to Select Which Files You Want to Consolidate
Set IndvFiles = Application.FileDialog(msoFileDialogOpen)
With IndvFiles
.AllowMultiSelect = True
.Title = "Multi-select target data files:"
.ButtonName = ""
.Filters.Clear
.Show
End With
Application.ScreenUpdating = False
Application.DisplayAlerts = False
CurrentSheets = ThisWorkbook.Worksheets.Count
BookCount = IndvFiles.SelectedItems.Count
Dim LROW as Long
DIM LROW2 as Long
DIM Import as Range
For x = 1 To BookCount
On Error GoTo StopHere:
Set Currentbook = Workbooks.Open(IndvFiles.SelectedItems(X))
For i = 1 To Currentbook.Worksheets.Count
LROW = thisworkbook.sheets("desired sheet name paste").Range("A2").End(XLdown).Rows
LROW2=currentbook.sheets(i).Range("A2").End(XLdown).Rows
Set Import = currentbook.sheets(i).Range("A2:Z"&LROW2)
Import.Copy
ThisWorkbook.Sheets("Desired sheet name paste range").Range("A"&LROW).PasteSpecial Paste:=xlPasteValues, operation:=xlNone, skipblanks _
Next i
Currentbook.Close False
Next x
StopHere:
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub

Copying worksheet data from multiple workbooks and pasting it into a master data file by worksheet

I am completely newbie to VBA however I was given a task to complete using VBA. How do I create a code which copies the data of multiple worksheets from different workbooks and pastes them into another workbook (master data file) by adding exactly the same number of separate worksheets to this master data file? That is, I would like to display all of those worksheets being copied over to separate worksheets in the master data file.
I have managed to pull off a code which copies the data over and pastes it into one single worksheet but I am struggling to get them copied over one by one to separate worksheets.
Your help is much appreciated.
Sub datatransfer()
Dim FolderPath, FilePath, Filename, targetfile As String
Dim wb1, wb2 As Workbook
Dim i, mycount As Long
targetfile = "Left the location out on purpose"
FolderPath = " Left the location out on purpose "
FilePath = FolderPath & "*.xls*"
Filename = Dir(FilePath)
Dim lastrow, lastcolumn As Long
Do While Filename < ""
mycount = mycount + 1
Filename = Dir()
Set wb1 = Workbooks.Open(FolderPath & Filename)
lastrow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
lastcolumn = ActiveSheet.Cells(1, Columns.Count).End(xlToLeft).Column
Range(Cells(2, 1), Cells(lastrow, lastcolumn)).Copy
Application.DisplayAlerts = False
Set wb2 = Workbooks.Open(targetfile)
Worksheets.Add Before:=Sheet1, Count:=2
For i = 1 To mycount
With Worksheets(i)
ActiveSheet.Paste Destination:=.Range(Cells(2, 2), Cells(2, lastcolumn))
End With
Next i
ActiveWorkbook.Close SaveChanges:=True
Filename = Dir
Loop
End Sub
See the code below. I made several notes where I modified the code a bit to ensure it works with hitches going forward.
Sub datatransfer()
'have to specify type for all variables, techinically it still works the way you did, but you are setting unncessary memory
Dim FolderPath As String, FilePath As String, Filename As String, targetfile As String
Dim wb1 As Workbook, wb2 As Workbook
targetfile = "Left the location out on purpose"
FolderPath = " Left the location out on purpose "
FilePath = FolderPath & "*.xls*"
Set wb2 = Workbooks.Open(targetfile) 'only need to open this once and leave open until execution is finished
Filename = Dir(FilePath)
Do While Filename <> "" ' need "<>" to say not equal to nothing
wb2.Worksheets.Add After:=wb2.Worksheets(wb2.Worksheets.Count) 'add new sheet to paste data in target book
Set wb1 = Workbooks.Open(FolderPath & Filename)
Dim lastrow As Long, lastcolumn As Long
With wb1.Worksheets(1) 'best to qualify all objects and work directly with them
lastrow = .Cells(.Rows.Count, 1).End(xlUp).Row
lastcolumn = .Cells(1, .Columns.Count).End(xlToLeft).Column
'pretty sure you want to add this A1, since it's a new blank sheet
.Range(.Cells(2, 1), .Cells(lastrow, lastcolumn)).Copy _
Destination:=wb2.Worksheets(wb2.Worksheets.Count).Range("A1")
End With
wb1.Close False 'assume no need to save changes to workbook you copied data from
Filename = Dir
Loop
wb2.Close True 'no close and save master file
End Sub

Excel Sheet Name Error

I'm using a VBA code to cycle through excel files in a directory and pull information from one worksheet and paste into a newly created worksheet. I'm also naming my new worksheets (in my destination file) by the name in one of the cells in the source file.
My code works for the first loop but fails/stops in the second loop (VBA points to an error in the Dest.Sheets.Add(After:=Dest.Sheets(Dest.Sheets.Count)).Name = Sheetname line. I need to loop through 75 of these files and I'm unsure of what's going on because it works correctly for the first file.
Thanks so much for the help!
Sub AddSummaryTables()
Dim Spath, Filename, Sheetname As String
Dim Source, Dest As Workbook
Dim WS As Worksheet
Set Dest = ThisWorkbook
Spath = InputBox("Enter File Source Path") & "\"
Filename = Dir(Spath & "*.xls*")
Do While Filename <> ""
Set Source = Workbooks.Open(Spath & Filename)
Sheetname = Source.Sheets("Summary").Range("B2").Text
MsgBox Sheetname
Dest.Sheets.Add(After:=Dest.Sheets(Dest.Sheets.Count)).Name = Sheetname
Source.Sheets("Summary").Range("A1:R150").Copy
Dest.Worksheets(Sheetname).Range("A1").PasteSpecial xlPasteValues
Dest.Worksheets(Sheetname).Range("A1").PasteSpecial xlPasteFormats
Dest.Worksheets(Sheetname).Range("A1:R150").WrapText = False
Dest.Worksheets(Sheetname).Rows.AutoFit
Dest.Worksheets(Sheetname).Columns.AutoFit
Source.Close SaveChanges:=False
Dest.Save
Filename = Dir()
Loop
End Sub
following Comintern's and Wyatt's suggestion you could try like follows
Option Explicit
Sub AddSummaryTables()
Dim sPath As String, fileName As String
Dim sourceWb As Workbook, destWb As Workbook
Dim sourceWs As Worksheet, destWs As Worksheet
Set destWb = ThisWorkbook
sPath = InputBox("Enter File Source Path") & "\"
fileName = Dir(sPath & "*.xls*")
Do While fileName <> ""
Set sourceWb = Workbooks.Open(sPath & fileName)
Set sourceWs = GetWorksheet(sourceWb, "Summary")
If Not sourceWs Is Nothing Then
Set destWs = SetWorksheet(destWb, sourceWs.Range("B2").Text)
sourceWs.Range("A1:R150").Copy
With destWs
.Range("A1").PasteSpecial xlPasteValues
.Range("A1").PasteSpecial xlPasteFormats
.UsedRange.WrapText = False
.Rows.AutoFit
.Columns.AutoFit
End With
sourceWb.Close SaveChanges:=False
destWb.Save
End If
fileName = Dir()
Loop
End Sub
Function GetWorksheet(wb As Workbook, sheetName As String) As Worksheet
On Error Resume Next
Set GetWorksheet = wb.Worksheets(sheetName)
On Error GoTo 0
End Function
Function SetWorksheet(wb As Workbook, sheetName As String) As Worksheet
Dim i As Integer
Do While Not GetWorksheet(wb, sheetName & IIf(i = 0, "", "-" & i)) Is Nothing
i = i + 1
Loop
With wb
.Worksheets.Add(After:=.Worksheets(.Worksheets.Count)).Name = sheetName & IIf(i = 0, "", "-" & Format(i, "000"))
Set SetWorksheet = .ActiveSheet
End With
End Function
where you make sure that
any opened workbook has a "Summary" worksheet
you name worksheets in your destination workbook such as not to have duplicates: if you happen to deal with say three worksheets named "Sheet5" then your destination workbook will have added worksheets "Sheet5", "Sheet5-001" and "Sheet5-002".
You're issue may be that when you are adding the sheet from the second workbook, it has the same name as the sheet from the first workbook. You could check if the sheet exists and add a number to it. The post below might help.
Test or check if sheet exists