Looking to Loop Excel VBA Macro through Multiple Worksheets? - vba

Looking to loop the following code through (about) 125 worksheets in an Excel workbook and pull the listed cell values into one database entry log on the 'Database' worksheet'. Right now it is only pulling from one of the tabs . (PO VT-0189). Wondering how to correct.
Private Sub PopulateOrderInfo()
Dim OrderDate As String, PONumber As String, Vendor As String, ShipTo As String, SKU As String
Dim R As Long, LastSKURow As Long, NextDBRow As Long, OFrm As Worksheet, DB As Worksheet
For Each OFrm In ActiveWorkbook.Worksheets
Set OFrm = Worksheets("PO VT-0189")
Set DB = Worksheets("Database")
OrderDate = OFrm.Range("N4")
PONumber = OFrm.Range("N3")
Vendor = OFrm.Range("A13")
ShipTo = OFrm.Range("I13")
POTotal = OFrm.Range("P43")
LastSKURow = OFrm.Range("A38").End(xlUp).Row
For R = 21 To LastSKURow
SKU = OFrm.Range("A" & R).Value
SKUDesc = OFrm.Range("D" & R).Value
SKUQty = OFrm.Range("K" & R).Value
Lntotal = OFrm.Range("M" & R).Value
NextDBRow = DB.Cells(DB.Rows.Count, "A").End(xlUp).Row + 1
DB.Range("A" & NextDBRow).Value = OrderDate
DB.Range("B" & NextDBRow).Value = PONumber
DB.Range("C" & NextDBRow).Value = Vendor
DB.Range("D" & NextDBRow).Value = ShipTo
DB.Range("E" & NextDBRow).Value = SKU
DB.Range("F" & NextDBRow).Value = SKUDesc
DB.Range("G" & NextDBRow).Value = SKUQty
DB.Range("H" & NextDBRow).Value = Lntotal
DB.Range("I" & NextDBRow).Value = POTotal
Next R
Next OFrm
End Sub

I think you can also shorten your code by avoiding the loop and most of the variables seem unnecessary to me.
Private Sub PopulateOrderInfo()
Dim R As Long, LastSKURow As Long, NextDBRow As Long, OFrm As Worksheet, DB As Worksheet
Set DB = Worksheets("Database")
For Each OFrm In ActiveWorkbook.Worksheets
If OFrm.Name <> DB.Name Then
LastSKURow = OFrm.Range("A38").End(xlUp).Row
R = LastSKURow - 21 + 1
NextDBRow = DB.Cells(DB.Rows.Count, "A").End(xlUp).Row + 1
DB.Range("A" & NextDBRow).Resize(R).Value = OFrm.Range("N4")
DB.Range("B" & NextDBRow).Resize(R).Value = OFrm.Range("N3")
DB.Range("C" & NextDBRow).Resize(R).Value = OFrm.Range("A13")
DB.Range("D" & NextDBRow).Resize(R).Value = OFrm.Range("I13")
DB.Range("E" & NextDBRow).Resize(R).Value = OFrm.Range("A21").Resize(R).Value
DB.Range("F" & NextDBRow).Resize(R).Value = OFrm.Range("D21").Resize(R).Value
DB.Range("G" & NextDBRow).Resize(R).Value = OFrm.Range("K21").Resize(R).Value
DB.Range("H" & NextDBRow).Resize(R).Value = OFrm.Range("M21").Resize(R).Value
DB.Range("I" & NextDBRow).Resize(R).Value = OFrm.Range("P43")
End If
Next OFrm
End Sub

Use a for loop and WorkSheets collection like:
For I = 1 to worksheets.count
if worksheets(i).name <> "Database" then
Add your code here
end if
Next i
This loops through every worksheet in your workbook and does what ever you need to all worksheets except the Database.

Using a for each... loop
For Each ws In wb.Worksheets
If ws.name = "Database" Then
'Leave blank to just skip database. Code here if you want something special on database. OR statements can be used to exclude additional sheets
Else
'Code here
End If
Next

I think you described the issue fairly well. Just to confirm, you want to loop through all worksheets in one single workbook, right. Try the script below. Feedback if you have additional questions, concerns, etc. Thanks.
Sub ImportAll()
Dim blnHasFieldNames As Boolean, blnEXCEL As Boolean, blnReadOnly As Boolean
Dim lngCount As Long
Dim objExcel As Object, objWorkbook As Object
Dim colWorksheets As Collection
Dim strPathFile as String, strTable as String
Dim strPassword As String
' Establish an EXCEL application object
On Error Resume Next
Set objExcel = GetObject(, "Excel.Application")
If Err.Number <> 0 Then
Set objExcel = CreateObject("Excel.Application")
blnEXCEL = True
End If
Err.Clear
On Error GoTo 0
' Change this next line to True if the first row in EXCEL worksheet
' has field names
blnHasFieldNames = False
' Replace C:\Filename.xls with the actual path and filename
strPathFile = "C:\Filename.xls"
' Replace tablename with the real name of the table into which
' the data are to be imported
strTable = "tablename"
' Replace passwordtext with the real password;
' if there is no password, replace it with vbNullString constant
' (e.g., strPassword = vbNullString)
strPassword = "passwordtext"
blnReadOnly = True ' open EXCEL file in read-only mode
' Open the EXCEL file and read the worksheet names into a collection
Set colWorksheets = New Collection
Set objWorkbook = objExcel.Workbooks.Open(strPathFile, , blnReadOnly, , _
strPassword)
For lngCount = 1 To objWorkbook.Worksheets.Count
colWorksheets.Add objWorkbook.Worksheets(lngCount).Name
Next lngCount
' Close the EXCEL file without saving the file, and clean up the EXCEL objects
objWorkbook.Close False
Set objWorkbook = Nothing
If blnEXCEL = True Then objExcel.Quit
Set objExcel = Nothing
' Import the data from each worksheet into the table
For lngCount = colWorksheets.Count To 1 Step -1
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, _
strTable, strPathFile, blnHasFieldNames, colWorksheets(lngCount) & "$"
Next lngCount
' Delete the collection
Set colWorksheets = Nothing
' Uncomment out the next code step if you want to delete the
' EXCEL file after it's been imported
' Kill strPathFile
End Sub

Related

VBA for copying multiple columns from different workbooks to be in columns next to each other

I am trying to pull data from a folder containing 300 Workbooks, each named 001, 002 etc.
I am only interested in pulling the data from column G of each file and copying it into a separate folder (each file does not have the same amount if data in row G)
I have been able to copy the data across, but I can't seem to get it to move past column 2 and instead writes over the previous column.
The output needed is:
data from column G workbook"001" pasted into "new sheet" column A
data from column G workbook"002" pasted into "new sheet" column B
and so on
Each file in the folder of 300 only has 1 worksheet each, each labelled: 001,002,...,300
This is the code I already had which results in 2 columns of data where 1 gets replaced by each new sheet instead.
Any help to solve this issue would be greatly appreciated.
Sub Copy()
Dim MyFile As String
Dim Filepath As String
Dim q As Long
Dim ThisCol As Integer
Dim ThisRow As Long
Dim CurS As Worksheet
Dim CurRg As Range
Dim InfCol As Integer
Set CurS = ActiveSheet
ThisRow = ActiveCell.Row
ThisCol = ActiveCell.Column
InfCol = 1
Filepath = "C:..."
MyFile = Dir(Filepath)
Do While Len(MyFile) > 0
If MyFile = "Text to column.xlsm" Then
Exit Sub
End If
Workbooks.Open (Filepath & MyFile)
LastRow = Range("G1").CurrentRegion.Rows.Count
Range("G1", Range("G" & LastRow)).Copy ThisWorkbook.Sheets("Sheet1").Range(CurS.Cells(ThisRow, ThisCol + 1), CurS.Cells(ThisRow, ThisCol + CurS.Cells(ThisRow, InfCol).Value))
ActiveWorkbook.Save
ActiveWorkbook.Close
MyFile = Dir
Loop
End Sub
To properly copy in a new column each time, you need a variable that increments during each loop to offset by one each time. When you use ThisCol + 1 you're always getting the same value because ThisCol is not updated.
Something like this:
Sub Copy()
Dim MyFile As String
Dim Filepath As String
Dim q As Long
Dim ThisCol As Integer
Dim ThisRow As Long
Dim CurS As Worksheet
Dim CurRg As Range
Dim InfCol As Integer
Set CurS = ActiveSheet
ThisRow = ActiveCell.Row
ThisCol = ActiveCell.Column
InfCol = 1
Filepath = ReplacewithyouFilePath
MyFile = Dir(Filepath)
Do While Len(MyFile) > 0
If MyFile = "Text to column.xlsm" Then
Exit Sub
End If
'Let's keep a reference to the workbook
Dim wb As Workbook
Set wb = Workbooks.Open(Filepath & MyFile)
'Let's keep a reference to the first sheet where the data is
Dim ws As Worksheet
Set ws = wb.Sheets(1)
Dim LastRow As Long
LastRow = ws.Range("G1").CurrentRegion.Rows.Count
'We create a variable to increment at each column
Dim Counter As Long
'Let's make the copy operation using the Counter
ws.Range("G1", ws.Range("G" & LastRow)).Copy CurS.Range(CurS.Cells(ThisRow, ThisCol + Counter), CurS.Cells(ThisRow + LastRow - 1, ThisCol + Counter))
'We increment the counter for the next file
Counter = Counter + 1
'We use wb to make sure we are referring to the right workbook
wb.Save
wb.Close
MyFile = Dir
'We free the variables for good measure
Set wb = Nothing
Set ws = Nothing
Loop
End Sub
Import Columns
Sub ImportColumns()
Const FOLDER_PATH As String = "C:\Test"
Const FILE_EXTENSION_PATTERN As String = "*.xls*"
Const SOURCE_WORKSHEET_ID As Variant = 1
Const SOURCE_COLUMN As String = "G"
Const SOURCE_FIRST_ROW As Long = 1
Const DESTINATION_WORKSHEET_NAME As String = "Sheet1"
Const DESTINATION_FIRST_CELL_ADDRESS As String = "A1"
Const DESTINATION_COLUMN_OFFSET As Long = 1
Dim pSep As String: pSep = Application.PathSeparator
Dim FolderPath As String: FolderPath = FOLDER_PATH
If Right(FolderPath, 1) <> pSep Then FolderPath = FolderPath & pSep
Dim DirPattern As String: DirPattern = FolderPath & FILE_EXTENSION_PATTERN
Dim SourceFileName As String: SourceFileName = Dir(DirPattern)
If Len(SourceFileName) = 0 Then
MsgBox "No files found.", vbExclamation
Exit Sub
End If
Dim dwb As Workbook: Set dwb = ThisWorkbook ' workbook containing this code
Dim dws As Worksheet: Set dws = dwb.Worksheets(DESTINATION_WORKSHEET_NAME)
Dim dfCell As Range: Set dfCell = dws.Range(DESTINATION_FIRST_CELL_ADDRESS)
Application.ScreenUpdating = False
Dim swb As Workbook
Dim sws As Worksheet
Dim srg As Range
Dim sfCell As Range
Dim slCell As Range
Do While Len(SourceFileName) > 0
If StrComp(SourceFileName, "Text to column.xlsm", vbTextCompare) _
<> 0 Then ' Why 'Exit Sub'? Is this the destination file?
Set swb = Workbooks.Open(FolderPath & SourceFileName, True, True)
Set sws = swb.Worksheets(SOURCE_WORKSHEET_ID)
Set sfCell = sws.Cells(SOURCE_FIRST_ROW, SOURCE_COLUMN)
Set slCell = sws.Cells(sws.Rows.Count, SOURCE_COLUMN).End(xlUp)
Set srg = sws.Range(sfCell, slCell)
srg.Copy dfCell
' Or, if you only need values without formulas and formats,
' instead, use the more efficient:
'dfCell.Resize(srg.Rows.Count).Value = srg.Value
Set dfCell = dfCell.Offset(, DESTINATION_COLUMN_OFFSET) ' next col.
swb.Close SaveChanges:=False ' we are just reading, no need to save!
'Else ' it's "Text to column.xlsm"; do nothing
End If
SourceFileName = Dir
Loop
Application.ScreenUpdating = True
MsgBox "Columns imported.", vbInformation
End Sub

Loop that adds a new excel sheet for each time button is clicked

I'm trying to add a new excel for each time a button is clicked, since the sheet is named after the date. However, I get an error that says "Cannot rename a sheet to the same name as another sheet, a referenced object library or a workbook refernced by Visual basic."
Dim szTodayDate As String
szTodayDate = Format(Date, "mm.dd")
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets.Add(After:= _
ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
ws.Name = szTodayDate
What I want is to create a new worksheet that will be named mm.dd.i. While i refers to the number of time I create a new worksheet using the button. Sorry, I'm a VBA newbie.
Thank you for the answers. Gary's Student Made the most efficient one. Solved.
How about:
Sub sjvyv()
Dim szTodayDate As String
szTodayDate = Format(Date, "mm.dd")
Dim ws As Worksheet, i As Long
ReDim N(1 To Sheets.Count)
i = 1
For Each ws In Sheets
If Left(ws.Name, 5) = szTodayDate Then
N(i) = Mid(wsname, 6)
i = i + 1
End If
Next ws
Set ws = ThisWorkbook.Sheets.Add(After:= _
ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
ws.Name = szTodayDate & "." & i
End Sub
Here is a snippet that creates a new name for the sheet, that is available:
Sub AddSheet()
Dim TodayDate As String
Dim i As Integer
TodayDate = Format(Date, "mm.dd")
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets.Add(After:= _
ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
i = 1
Do While Not SheetNameAvailable(TodayDate & "." & i)
i = i + 1
Loop
ws.Name = TodayDate & "." & i
End Sub
Function SheetNameAvailable(SheetName As String) As Boolean
Dim ws As Worksheet
On Error Resume Next
Err.Clear
Set ws = ThisWorkbook.Worksheets(SheetName)
SheetNameAvailable = (Err.Number <> 0)
On Error GoTo 0
End Function
On Error Resume Next
Set tempWS = Sheets(szTodayDate)
ws.Name = szTodayDate & IIf(tempWS Is Nothing, "", GetSheetCount(szTodayDate))
Set tempWS = Nothing
On Error GoTo 0
Function GetSheetCount(dateToTest) As Integer
Dim i As Integer
i = 1
For Each sh In ThisWorkbook.Sheets
If sh.Name Like dateToTest & "*" Then
i = i + 1
End If
Next
GetSheetCount = i
End Function
ws.Name = szTodayDate & ThisWorkbook.Sheets.Count + 1
Just append the count of sheets (+1) to the end.

Excel VBA code error type mismatch using worksheetfunction to find duplicates

I get a
Type Mismatch Error "13"
with the below code. Can anyone assist with where I'm going wrong with my VBA syntax and use of variables.
If Application.WorksheetFuntion.CountIf(Target, r.Value) > 1 Then
I've tried the matchFoundIndex code method to no success...Likely due to incorrect VBA syntax.
The intent of the CountIf line is to look for duplicates in column A. The rest of the code loops through files and worksheets copying the file name, worksheet name, and cell C1 for further analysis. I am a novice at coding and I'm sure there may be Dimmed variables that I'm not using, other formatting, and errors that I have not found yet. Any Help would be appreciative.
Sub CopyFileAndStudyName()
Dim sPath As String, SName As String
Dim xlWB As Workbook
Dim sh As Worksheet
Dim lngRow As Long
Dim lngwsh As Long
Dim xlApp As Excel.Application
Dim sfile As String
Dim wbk As Workbook
Dim iCntr As Long
Dim matchFoundIndex As Long
Dim FindDuplicates As Boolean
Dim IsDup As Boolean
sPath = "C:\Users\mypath\"
' which row to begin writing to in the activesheet
lngRow = 2
SName = Dir(sPath & "*.xlsx") ' for xl2007 & "*.xls"
Set xlApp = New Excel.Application
xlApp.Visible = False
If MsgBox("Are you sure you want to copy all the file and Cell C1 in " & sPath & "?", vbYesNo) = vbNo Then Exit Sub
Do While SName <> ""
lngwsh = 1
' Will cycle through all .xlsx files in sPath
Set xlWB = xlApp.Workbooks.Open(sPath & SName, , True) ' opens in read-only mode
' Will cycle through first 3 of the worksheets in each file copying file name and cell C1 in columns C and D
For lngwsh = 1 To 3
Set sh = ActiveSheet
sh.Cells(lngRow, "A") = xlWB.Name
sh.Cells(lngRow, "B") = xlWB.Worksheets(lngwsh).Range("C1")
sh.Cells(lngRow, "C") = xlWB.Sheets(lngwsh).Name
Dim Target As Range
Dim r As Range
Dim lastRow As Long
Dim ws As Worksheet
Set ws = xlWB.Worksheets(lngwsh)
With ws
lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
Set Target = ws.Range("A1:A" & lastRow)
End With
For Each r In Target
If r.Value <> "" Then
If Application.WorksheetFunction.CountIf(Target, r.Value) > 1 Then
FindDuplicates = True
Exit For
Else
FindDuplicates = False
End If
End If
Next r
Debug.Print FindDuplicates
IsDup = FindDuplicates
sh.Cells(lngRow, "D") = IsDup
FindDuplicates = False
End If
lngRow = lngRow + 1
Next lngwsh
xlWB.Close False
xlApp.Quit
SName = Dir()
Loop
MsgBox "Report Ready!"
End Sub
If you want to check for Duplicates in a Range, you can use a Dictionary object.
Dim Dict As Object
Set Dict = CreateObject("Scripting.Dictionary")
For Each r In Target
If Trim(r.Value) <> "" Then
If Not Dict.exists(r.Value) Then ' not found in dictionary >> add Key
Dict.Add r.Value, r.Value
FindDuplicates = False
Else ' found in Dictionary >> Exit
FindDuplicates = True
Exit For
nd If
End If
Next r
Sub CopyFileAndStudyName()
Dim sPath As String, SName As String
Dim xlWB As Workbook
Dim sh As Worksheet
Dim lngRow As Long
Dim lngwsh As Long
Dim xlApp As Excel.Application
Dim sfile As String
Dim wbk As Workbook
Dim iCntr As Long
Dim matchFoundIndex As Long
Dim FindDuplicates As Boolean
Dim IsDup As Boolean
sPath = "C:\Users\mypath\"
' which row to begin writing to in the activesheet
lngRow = 2
SName = Dir(sPath & "*.xlsx") ' for xl2007 & "*.xls"
Set xlApp = New Excel.Application
xlApp.Visible = False
If MsgBox("Are you sure you want to copy all the file and Cell C1 in " & sPath & "?", vbYesNo) = vbNo Then Exit Sub
Do While SName <> ""
lngwsh = 1
' Will cycle through all .xlsx files in sPath
Set xlWB = xlApp.Workbooks.Open(sPath & SName, , True) ' opens in read-only mode
' Will cycle through first 3 of the worksheets in each file copying file name and cell C1 in columns C and D
For lngwsh = 1 To 3
Set sh = ActiveSheet
sh.Cells(lngRow, "A") = xlWB.Name
sh.Cells(lngRow, "B") = xlWB.Worksheets(lngwsh).Range("C1")
sh.Cells(lngRow, "C") = xlWB.Sheets(lngwsh).Name
Dim Target As Range
Dim r As Range
Dim lastRow As Long
Dim ws As Worksheet
Set ws = xlWB.Worksheets(lngwsh)
With ws
lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
Set Target = ws.Range("A1:A" & lastRow)
End With
For Each r In Target
If r.Value <> "" Then
If Application.WorksheetFunction.CountIf(Target, r.Value) > 1 Then
FindDuplicates = True
Exit For
Else
FindDuplicates = False
End If
End If
Next r
Debug.Print FindDuplicates
IsDup = FindDuplicates
sh.Cells(lngRow, "D") = IsDup
FindDuplicates = False
lngRow = lngRow + 1
Next lngwsh
xlWB.Close False
xlApp.Quit
SName = Dir()
Loop
MsgBox "Report Ready!"
End Sub
I was having a similar experience using CountIF and passing it a range. In my case I was using:
i = Application.WorksheetFunction.CountIf(ws.UsedRange, r.Value)
which was giving me a Type Mismatch error. I had seen other people having success with the first parameter wrapped in Range() so after a few tries I found out that this would work:
i = Application.WorksheetFunction.CountIf(Range(ws.UsedRange.Address), r.Value)
So, I suggest that you change your code to this and see if it works:
If Application.WorksheetFuntion.CountIf(Range(Target.Address), r.Value) > 1 Then

when Relative path of input file Included in script Error reported -VBA

I have this macro which is taking input excel, and generating excel report and copying it. Below code works fine when i am running manually from excel with msg dialog box, however when i tried to pass relative path of input file, i am getting "Runtime Error 9"-Subscript out of range. While debugger points to Each sh as error context.
How do I fix this?
Sub buildSCTR()
'
' Merge CSV and built pivot for SCTR
' Ver 0.1
' 5-July-2017 P. Coffey
'
Const FILELIMIT = 0 'used to hardcode number of files will work with. better ways exist but this will do for now
Dim firstFilename As String
Dim secondFilename As String
Dim outputFilename As String
Dim element As Variant
Dim dirLocation As String
Dim macroWb As Object
Dim lastrow As Integer
Dim samName As String
Dim RootFolder As String
'code allows for multiple import, but using it for one one import here
Dim filenameArr(0 To FILELIMIT) As Variant 'so can push cells into it later
Dim inputSelected As Variant 'has to variant to iterate over via for each even though its a string
Set macroWb = ThisWorkbook
RootFolder = ActiveWorkbook.Path
'get new csv to load
'Set fd = Application.FileDialog(msoFileDialogFilePicker)
' With fd
' .AllowMultiSelect = True
' .Title = "Pick SC file to load"
'.Filters.Clear
'.Filters.Add "csv", "*.csv*"
'If .Show = True Then
' i = 0
' For Each inputSelected In .SelectedItems
' filenameArr(i) = Dir(inputSelected) 'kludgy....
' dirLocation = Split(inputSelected, filenameArr(i))(0)
' i = i + 1
'Next inputSelected
' Else
' MsgBox ("Nothing selected")
' Exit Sub
' End If
'End With
Application.StatusBar = "Starting to update"
element = RootFolder + "/Output/_SCT_Details_With_Comments.csv"
' For Each element In filenameArr()
If Not IsEmpty(element) Then 'as hardcoded length of array have to do this
Workbooks.Open (element)
Call CopyWorkbook(CStr(element), macroWb.Name)
'close csv as done with it
Workbooks(element).Close SaveChanges:=False
End If
'Next element
'convert to table
samName = ActiveSheet.Range("A2").Value
ActiveSheet.Name = samName & "_SCT_Data"
'assumes col A is contiguous
lastrow = ActiveSheet.Range("A1").End(xlDown).Row
ActiveSheet.ListObjects.Add(xlSrcRange, Range("$A1:$U" & lastrow), , xlYes).Name = "SCT"
'build pivot
Dim objWs As Worksheet
Dim objPT As PivotTable
Dim objPC As PivotCache
Sheets.Add.Name = "Summary"
Set objWs = ActiveSheet
Set objPC = ActiveWorkbook.PivotCaches.Create(xlDatabase, "SCT")
Set objPT = objPC.CreatePivotTable(objWs.Range("A3"), TableName:="SCTR")
With ActiveSheet.PivotTables("SCTR").PivotFields("Target_SC")
.Orientation = xlColumnField
.Position = 1
End With
With ActiveSheet.PivotTables("SCTR").PivotFields("Action")
.Orientation = xlRowField
End With
ActiveSheet.PivotTables("SCTR").AddDataField ActiveSheet.PivotTables( _
"SCTR").PivotFields("PNI_SC"), "Count of PNI_SC", xlCount
'have to do it in this order else vba was removing pni_sc from row field...who knows why
With ActiveSheet.PivotTables("SCTR").PivotFields("PNI_SC")
.Orientation = xlRowField
.Position = 1
End With
'--update sheet with last sync info
macroWb.Sheets("Summary").Range("A1").Value = samName
macroWb.Sheets("Summary").Range("A3").NumberFormat = "h:mm dd/mm"
'save as new file
Dim timestamp As String
timestamp = Format(Now(), "mmddhh")
ActiveWorkbook.SaveAs Filename:= _
dirLocation & samName & "_SCTR_" & timestamp & ".xlsm" _
, FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False
'exit msg
Application.StatusBar = False
Application.ScreenUpdating = True
MsgBox ("Completed - saved file as " & dirLocation & samName & "_SCTR_" & timestamp & ".xlsm")
End Sub
Sub CopyWorkbook(source As String, target As String)
'copy all sheets from one workbook to another
Dim sh As Worksheet, wb As Workbook
Set wb = Workbooks(target)
For Each sh In Workbooks(source).Worksheets
sh.Copy After:=wb.Sheets(wb.Sheets.Count)
Next sh
End Sub
the problem is due to the fact that the source contains the fullname of the workbook (path included) and Excel expects only the shortname of the workbook (without the path)
so adapt the call instruction like this
Call CopyWorkbook(ActiveWorkbook.Name, macroWb.Name)

copying data from a folder of workbooks into a single worksheet iteration through loop in VBA

I am trying to copy data from a couple of workbooks present in a folder into a single workbook. I am looping through the folder to fetch the data from the various workbooks but I need to paste the data spanning from A5:D5 in loop.
i.e A5:D5 in the destination sheet is one workbook's data in the folder, I need the other set of data to be copied into A6:D6 and so on for the number of workbooks in the folder. Please help me loop through this.
Private Sub CommandButton1_Click()
Dim wbk As Workbook
Dim Filename As String
Dim Path As String
Path = "D:\Macro_Demo\estimation_sheets\"
Filename = Dir(Path & "*.xls")
Set target = Workbooks.Open("D:\Macro_Demo\Metrics_Macro_dest")
'--------------------------------------------
'OPEN EXCEL FILES
Do While Len(Filename) > 0 'IF NEXT FILE EXISTS THEN
Set wbk = Workbooks.Open(Path & Filename)
target.Sheets("Metrics_Data").Range("A5").Value = wbk.Sheets("summary").Range("I5").Value
target.Sheets("Metrics_Data").Range("B5").Value = wbk.Sheets("summary").Range("I6").Value + wbk.Sheets("summary").Range("I7")
target.Sheets("Metrics_Data").Range("C5").Value = wbk.Sheets("summary").Range("I8").Value
target.Sheets("Metrics_Data").Range("D5").Value = wbk.Sheets("summary").Range("I9").Value
MsgBox Filename & " has opened"
wbk.Close True
Filename = Dir
Loop
MsgBox "Task complete!"
End Sub
Try this:
Private Sub CommandButton1_Click()
Dim wbk As Workbook, target As Workbook, excelFile As String, path As String, rw As Integer
path = "D:\Macro_Demo\estimation_sheets\"
excelFile = Dir(path & "*.xls")
rw = 5
Set target = Workbooks.Open("D:\Macro_Demo\Metrics_Macro_dest")
Do While excelFile <> ""
Set wbk = Workbooks.Open(path & excelFile)
With target.Sheets("Metrics_Data")
.Range("A" & rw) = wbk.Sheets("summary").Range("I5")
.Range("B" & rw) = wbk.Sheets("summary").Range("I6") + wbk.Sheets("summary").Range("I7")
.Range("C" & rw) = wbk.Sheets("summary").Range("I8")
.Range("D" & rw) = wbk.Sheets("summary").Range("I9")
End With
wbk.Close True
rw = rw + 1
excelFile = Dir
Loop
MsgBox "Task complete!"
End Sub
You need to find the next available row on your destination sheet, store that in a variable, and write the data relative to that cell. Like this
Private Sub CommandButton1_Click()
Dim shSource As Worksheet, shDest As Worksheet
Dim sFile As String
Dim rNextRow As Range
Const sPATH As String = "D:\Macro_Demo\estimation_sheets\"
'Open the destination workbook
Set shDest = Workbooks.Open("D:\Macro_Demo\Metrics_Macro_dest.xls").Worksheets("Metrics_Data")
sFile = Dir(sPATH & "*.xls")
Do While Len(sFile) > 0
Set shSource = Workbooks.Open(sPATH & sFile).Worksheets("summary")
'start at row 1000 and go up until you find something
'then go down one row
Set rNextRow = shDest.Cells(1000, 1).End(xlUp).Offset(1, 0)
'Write the values relative to rNextRow
With rNextRow
.Value = shSource.Range("I5").Value
.Offset(0, 1).Value = shSource.Range("I6").Value
.Offset(0, 2).Value = shSource.Range("I8").Value
.Offset(0, 3).Value = shSource.Range("I9").Value
End With
'Close the source
shSource.Parent.Close False
sFile = Dir
Loop
MsgBox "Done"
End Sub