Merge Multiple Excel Sheets Into Summary Sheet - vba

I wonder whether someone may be able to help me please.
I'm using the code below to allow the user to copy from multiple Excel workbooks and merge the data into a Summary sheet.
Sub Merge()
Dim DestWB As Workbook, WB As Workbook, WS As Worksheet, SourceSheet As String
Set DestWB = ActiveWorkbook
SourceSheet = "Input"
startrow = 7
FileNames = Application.GetOpenFilename( _
filefilter:="Excel Files (*.xls*),*.xls*", _
Title:="Select the workbooks to merge.", MultiSelect:=True)
If IsArray(FileNames) = False Then
If FileNames = False Then
Exit Sub
End If
End If
For n = LBound(FileNames) To UBound(FileNames)
Set WB = Workbooks.Open(Filename:=FileNames(n), ReadOnly:=True)
For Each WS In WB.Worksheets
If WS.Name = SourceSheet Then
With WS
If .UsedRange.Cells.Count > 1 Then
dr = DestWB.Worksheets("Input").Range("C" & Rows.Count).End(xlUp).Row + 1
lastrow = .Range("C" & Rows.Count).End(xlUp).Row
For j = lastrow To startrow Step -1
If Range("E" & j) <> "Requirements Manager" And Range("E" & j) <> "R & D Lead" And Range("E" & j) <> "Technical" And Range("E" & j) <> "Analyst" Then Rows(j).Delete
Next
lastrow = .Range("C" & Rows.Count).End(xlUp).Row
If lastrow >= startrow Then
.Range("A" & startrow & ":AQ" & lastrow).Copy
DestWB.Worksheets("Input").Cells(dr, "A").PasteSpecial xlValues
End If
End If
End With
Exit For
End If
Next WS
WB.Close savechanges:=False
Next n
End Sub
The code works fine but I'm stuck with a problem related to the copying of the information, which is this line of code:
.Range("A" & startrow & ":AQ" & lastrow).Copy
I need to change this so that it takes into account two ranges. These are columns "B:AD" and "AF:AQ", but I'm not sure how to do this.
I just wondered wehether someone could possibly take a look at this please and offer some guidance on how I may go about solving this.
Many thanks and kind regards

In all the following I assume that you indeed don't want column A copied to the destination workbook and sheet.
You could use Union to copy paste it in one go (then any columns in between it will not be reflected when pasting:
If lastrow >= startrow Then
Union(.Range("B" & startrow & ":AD" & lastrow), .Range("AF" & startrow & ":AQ" & lastrow).Copy
DestWB.Worksheets("Input").Cells(dr, "B").PasteSpecial xlValues
End If
If you want it pasted with room between it as well then you could simply r3epeat the copy and paste lines:
If lastrow >= startrow Then
.Range("B" & startrow & ":AD" & lastrow).Copy
DestWB.Worksheets("Input").Cells(dr, "B").PasteSpecial xlValues
.Range("AF" & startrow & ":AQ" & lastrow).Copy
DestWB.Worksheets("Input").Cells(dr, "AF").PasteSpecial xlValues
End If

Related

Excel/VBA - Combine rows and columns from worksheets into one, with varying source columns

I am working on combining multiple Excel worksheets into a single Master worksheet. The following code works for when all worksheets have identical columns:
Sub CombineData()
Dim Sht As Worksheet
'This If will clear Master before combining
Worksheets("Master").Range("A2:ZZ9000").ClearContents
For Each Sht In ActiveWorkbook.Worksheets
If Sht.Name <> "Master" And Sht.Range("A2").Value <> "" Then
Sht.Select
LastRow = Range("A9000").End(xlUp).Row
Range("A2", Cells(LastRow, "ZZ")).Copy
Sheets("Master").Select
Range("A9000").End(xlUp).Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Else
End If
Next Sht
End Sub
However, I now need to go one step further and merge worksheets when the columns differ from the source worksheets, into a master which has all coluns listed.
This shows the layout of the worksheets I'm testing with, to keep things simple.
I'm open to either mapping all source to destination columns (e.g.
-Source1, Column A to Master, Column A
-Source2, Column B to Master, Column D
-Etc
Or simply recreating Master with all columns from source worksheets - which is preferable in case source worksheets change.
Cheers-
I have made some changes to your code, to make it suitable for mapping any column from master to sheet1. You have to hard code the mapping inside the code
Sub CombineData()
Dim Sht As Worksheet
Dim colname As String
Dim Lastrow As Integer, rowcount As Integer
'This If will clear Master before combining
Worksheets("Master").Range("A2:ZZ9000").ClearContents
colname = 1
For Each Sht In ActiveWorkbook.Worksheets
If Sht.Name = "Sheet2" And Sht.Range("A2").Value <> "" Then
Lastrow = Range("A9000").End(xlUp).Row
Sheets("Master").Select
rowcount = Range("A9000").End(xlUp).Row
Sht.Select
'Map the columns of sheet2 to master
Sheets("Master").Range("A" & rowcount & ":A" & rowcount + Lastrow - 2).Value = Sht.Range("A2:A" & Lastrow).Value
Sheets("Master").Range("B" & rowcount & ":B" & rowcount + Lastrow - 2).Value = Sht.Range("C2:C" & Lastrow).Value
ElseIf Sht.Name = "Sheet3" And Sht.Range("A2").Value <> "" Then
Lastrow = Range("A9000").End(xlUp).Row
Sheets("Master").Select
rowcount = Range("A9000").End(xlUp).Row
Sht.Select
'Map the columns of sheet3 to master
Sheets("Master").Range("A" & rowcount & ":A" & rowcount + Lastrow - 2).Value = Sht.Range("A2:A" & Lastrow).Value
Sheets("Master").Range("B" & rowcount & ":B" & rowcount + Lastrow - 2).Value = Sht.Range("B2:B" & Lastrow).Value
End If
Next Sht
End Sub
**************Edited********************
Sub CombineData()
Dim Sht As Worksheet
Dim colname As String
Dim Lastrow As Integer, rowcount As Integer
'This If will clear Master before combining
Worksheets("Master").Range("A2:ZZ9000").ClearContents
colname = 1
For Each Sht In ActiveWorkbook.Worksheets
If Sht.Name = "Sheet1" And Sht.Range("A2").Value <> "" Then
Sheets("Sheet1").Select
Lastrow = Range("A9000").End(xlUp).Row
Sheets("Master").Select
rowcount = Range("A9000").End(xlUp).Row + 1
Sht.Select
'Map the columns of sheet2 to master
Sheets("Master").Range("A" & rowcount & ":A" & rowcount + Lastrow - 2).Value = Sht.Range("A2:A" & Lastrow).Value
Sheets("Master").Range("B" & rowcount & ":B" & rowcount + Lastrow - 2).Value = Sht.Range("B2:B" & Lastrow).Value
Sheets("Master").Range("C" & rowcount & ":C" & rowcount + Lastrow - 2).Value = Sht.Range("C2:C" & Lastrow).Value
Sheets("Master").Range("D" & rowcount & ":D" & rowcount + Lastrow - 2).Value = Sht.Range("D2:D" & Lastrow).Value
ElseIf Sht.Name = "Sheet2" And Sht.Range("A2").Value <> "" Then
Sheets("Sheet2").Select
Lastrow = Range("A9000").End(xlUp).Row
Sheets("Master").Select
rowcount = Range("A9000").End(xlUp).Row + 1
Sht.Select
'Map the columns of sheet3 to master
Sheets("Master").Range("A" & rowcount & ":A" & rowcount + Lastrow - 2).Value = Sht.Range("A2:A" & Lastrow).Value
Sheets("Master").Range("E" & rowcount & ":E" & rowcount + Lastrow - 2).Value = Sht.Range("B2:B" & Lastrow).Value
Sheets("Master").Range("F" & rowcount & ":F" & rowcount + Lastrow - 2).Value = Sht.Range("C2:C" & Lastrow).Value
Sheets("Master").Range("G" & rowcount & ":G" & rowcount + Lastrow - 2).Value = Sht.Range("D2:D" & Lastrow).Value
Sheets("Master").Range("C" & rowcount & ":C" & rowcount + Lastrow - 2).Value = Sht.Range("E2:E" & Lastrow).Value
End If
Next Sht
End Sub

Method of Range Object_Worksheet failed error in copying and pasting data from a worksheet to another

I am trying to copy and paste data from an input sheet into an output sheet, and once the data is in the next spreadsheet, it will be filled down the next rows from a starting date to an ending date.
As is, the code gets me the following errors when debugging:
ws1.Range("A" & NextRow) = Method of Range Object_Worsheet failed; same for ws1.Range("B" & NextRow); ws1.Range("C" & NextRow) etc...
ws1.Cells(LastRow, "H") = Application-defined or object-defined error.
Also, I noticed that when I set RawDataEntries it equals 37, that is the last non-empty row, but then when I try to use the For loop and point my mouse on RawDataEntries in For n=1 To RawDataEntries, VBA returns me a value of 105, which seems to come out of nowhere.
I think the logic behind the code is correct. What might have gone wrong?
Sub AddFlight_Click()
Const RNG_END_DT As String = "N2"
Dim NextRow1 As Long, LastRow1 As Long, ws1 As Worksheet
Dim ws2 As Worksheet, RawDataEntries As Long
Set ws1 = Sheets("JetAir Flight Plan")
Set ws2 = Sheets("TUI B Flight Plan")
LastRow1 = ws1.Range("A" & Rows.Count).End(xlUp).Row
NextRow1 = LastRow1 + 1
RawDataEntries = ws2.Range("A" & Rows.Count).End(xlUp).Row
For n = 1 To RawDataEntries
'Data from an input worksheet is copied and pasted into specific cells in an output worksheet.
ws1.Range("A" & NextRow).Value = ws2.Range("A" & n).Value
ws1.Range("B" & NextRow).Value = ws2.Range("B" & n).Text
ws1.Range("D" & NextRow).Value = ws2.Range("D" & n).Text
ws1.Range("E" & NextRow).Value = ws2.Range("E" & n).Text
ws1.Range("F" & NextRow).Value = ws2.Range("F" & n).Text
ws1.Range("G" & NextRow).Value = ws2.Range("G" & n).Text
ws1.Range(RNG_END_DT).Value = ws2.Range("H" & n).Value
'A series of dates is created from a starting date
' to an ending date in column A of ws1.
ws1.Range("A" & NextRow).DataSeries Rowcol:=xlColumns, _
Type:=xlChronological, Date:=xlDay, Step:=7, _
Stop:=ws1.Range(RNG_END_DT).Value, Trend:=False
'The data filled in the last row with the userform data through
' the first part of the macro will be copied and pasted in
' the next row until there is a blank cell in column A.
LastRow1 = ws1.Range("A" & Rows.Count).End(xlUp).Row
ws1.Range(ws1.Range("B" & NextRow), ws1.Cells(LastRow, "H")).FillDown
'We repeat the process for other rows on the sheet data are pulled from
Next n
Thanks a lot.
Change NextRow to NextRow1. Right now you are calling a variable that doesn't exist.
Or you can do the opposite (NextRow1 to NextRow)
Same with LastRow and LastRow1

Copy certain cells to a specific place in a new workbook using For, If, Then conditions

I want to copy certain cells (for, if then condition) to an other sheet. I got great help with my code and it smoothly runs through the lines so far, but still it doesn't do exactly what I want.
I want to look for the value 848 in column A, if there is 848 in a certain row X, I want to copy the content of the following cells: XA, XN, XO, XAM, AH, XP XE and XF to the other worksheet. But: the columns do not remain the same. They change from one to the other workbook like:
Copy value in the column X in “source” --> Column Y in “target”
A --> A, N-->B, O-->C, AM -->D, AH -->G, P-->I, E-->J, F-->K
After checking and copy pasting all the needed cells of rows containing 848 in column A, we do the same for the rows containing 618 in column A.
A --> A N-->B O-->C AM -->D T -->G P-->I E-->J F-->K
As I said, the code in general works properly, it's just that I don't get the right values to the cell I want them to. Any ideas? Thanks a lot!
Sub CopyToNewBook()
On Error Resume Next
Dim wbSrc As Workbook: Set wbSrc = Workbooks("invoices_eCMS.xlsx")
Dim wbDest As Workbook: Set wbDest = Workbooks("destination.xlsx")
If wbSrc Is Nothing Or wbDest Is Nothing Then
MsgBox "Please open both workbooks required"
Exit Sub
End If
On Error GoTo 0
Dim SearchValues() As String: SearchValues = Split("848,618", ",")
Dim wsSrc As Worksheet: Set wsSrc = wbSrc.Sheets("Data exAlps")
Dim wsDest As Worksheet: Set wsDest = wbDest.Sheets("Sheet1")
Dim LastRow As Long, i As Long, j As Long, z As Long: z = 63976
With wsSrc
LastRow = .Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
For j = 0 To UBound(SearchValues)
For i = 2 To LastRow
If .Cells(i, 1).Value = SearchValues(j) Then
.Range(.Cells(i, 1), .Cells(i, 14)).Copy
'.Cells(i, 1).Copy
wsDest.Range("A" & z).PasteSpecial xlPasteValues
z = z + 1
', .Cells(i, 14)).Copy
End If
Next i
Next j
End With
End Sub
Updated Code:
Sub CopyToNewBook()
On Error Resume Next
Dim wbSrc As Workbook: Set wbSrc = Workbooks("invoices_eCMS.xlsx")
Dim wbDest As Workbook: Set wbDest = Workbooks("destination.xlsx")
If wbSrc Is Nothing Or wbDest Is Nothing Then
MsgBox "Please open both workbooks required"
Exit Sub
End If
On Error GoTo 0
Dim SearchValues() As String: SearchValues = Split("848,618", ",")
Dim wsSrc As Worksheet: Set wsSrc = wbSrc.Sheets("Data exAlps")
Dim wsDest As Worksheet: Set wsDest = wbDest.Sheets("Sheet1")
Dim LastRow As Long, i As Long, j As Long, z As Long: z = 63976
With wsSrc
LastRow = .Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
For j = 0 To UBound(SearchValues)
For i = 2 To LastRow
If .Cells(i, 1).Value = SearchValues(j) Then
wsDest.Range("A" & z).Value = .Range("A" & i).Value
wsDest.Range("B" & z).Value = .Range("N" & i).Value
wsDest.Range("C" & z).Value = .Range("O" & i).Value
wsDest.Range("D" & z).Value = .Range("AM" & i).Value
wsDest.Range("G" & z).Value = .Range("AH" & i).Value
wsDest.Range("I" & i).Value = .Range("P" & z).Value
wsDest.Range("J" & i).Value = .Range("E" & z).Value
wsDest.Range("K" & i).Value = .Range("F" & z).Value
z = z + 1
', .Cells(i, 14)).Copy
End If
Next i
Next j
End With
End Sub
The problem exists here:
.Range(.Cells(i, 1), .Cells(i, 14)).Copy
wsDest.Range("A" & z).PasteSpecial xlPasteValues
where are you defining a specific range to copy and specific place to paste.
Since you want to copy certain columns in one sheet to different columns in your other sheet, you'll need to specify each one separately. See my example below. I didn't do each iteration, but you can just copy the code I wrote and adjust for each:
wsDest.Range("A" & z).Value = .Range("A" & i).Value
wsDest.Range("B" & z).Value = .Range("N" & i).Value
wsDest.Range("C" & z).Value = .Range("O" & i).Value
'... and so on for each cell that needs to be copied
If it's not clear, replace the code where I stated the problem was with the code I provided as a solution.

Merging 3 Sheets Into 1 Sheet

I want a script that pulls 3 different worksheets from another workbook and just stack the data in a new blank sheet.
This seems like it should work but it's not:
Sub CombineSheets()
Set NewSheet = Worksheets("Sheet2")
Set MC = Workbooks.Open("S:\OtherWorkBook.xlsm")
Set T1 = MC.Worksheets("T1")
Set T2 = MC.Worksheets("T2")
Set T3 = MC.Worksheets("T3")
With T1
lastrow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("A5:I" & lastrow).Copy NewSheet.Range("A" & wks.Rows.Count).End(xlUp)
End With
With T2
lastrow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("A5:I" & lastrow).Copy NewSheet.Range("A" & wks.Rows.Count).End(xlUp)
End With
With T3
lastrow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("A5:I" & lastrow).Copy NewSheet.Range("A" & wks.Rows.Count).End(xlUp)
End With
Workbooks("OtherWorkBook.xlsm").Close SaveChanges:=False
End Sub
The script runs but nothing is dumped into NewSheet? What am I missing. Thank you!
You are missing Destination:= after your .Copy call.
With T1
lastrow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("A5:I" & lastrow).Copy Destination:=NewSheet.Range("A" & NewSheet.Rows.Count).End(xlUp)
End With
This worked for me. I also changed wks to NewSheet. because your code doesn't clarify what wks exactly is.

Trying to use Excel VBA to skip blank rows in my copy/paste loop

I have a copy / paste loop for line items in an Excel file that exports data from these line items into an Excel-based form and saves each form by the value in Row B. My issue is that these line items are divided into 3 different tables on the same sheet, each with a different number of line items to be copied. Furthermore, each table is separated by 2 blank rows.
What I need the macro to do for me:
Start at line 17 and copy all line items in the first table until it hits a blank row - this varies from 1 to 600 rows.
Skip to SecondTable and perform the same functions.
Repeat for ThirdTable
Ignore some of the declarations as I deleted a large chunk of code for readability. I figured I would need 3 separate copy/paste loops to accomplish this (I've only included 2 here) and I tried using .Find to reference the start of the second/third tables. The macro runs as normal through the first table, but doesn't stop when it hits a blank row and fails when it tries to save a file based on the value of an empty cell. I believe the issue lies with the EndOne = .Range("B" & .Rows.Count).End(xlUp).Row argument right under With wsSource. Instead of counting only the non-blank rows of the first table, it counts the number of rows through the end of the third table.
Sub CopyToForm()
Dim wbSource As Workbook, wbForm As Workbook
Dim wsSource As Worksheet, wsForm As Worksheet
Dim formpath As String, foldertosavepath As String
Dim EndOne As Long, EndTwo As Long, EndThree As Long, i As Integer
Dim strProcessingFormPath As String
'Dim strCancel As String
'Dim strFilt As String
'Dim intFilterIndex As Integer
'Dim strDialogueFileTitle As String
Dim SecondTable As String
Dim ThirdTable As String
Set wbSource = ThisWorkbook '~~> Write your code in Indication Tool.xls
Set wsSource = wbSource.Sheets("Indication Tool") '~~> Put the source sheet name
With wsSource
'~~> Counts how many rows are in the Indication Tool
EndOne = .Range("B" & .Rows.Count).End(xlUp).Row
If EndOne < 17 Then MsgBox "No data for transfer": Exit Sub
For i = 17 To EndOne
Set wbForm = Workbooks.Open(formpath) '~~> open the form
Set wsForm = wbForm.Sheets("Processing Form") '~~> Declare which worksheet to activate
'~~> Proceed with the copying / pasting of values
.Range("B" & i).Copy wsForm.Range("F7:K7")
.Range("C" & i).Copy: wsForm.Range("D8").PasteSpecial xlPasteValues
.Range("C" & i).Copy: wsForm.Range("D30").PasteSpecial xlPasteValues
.Range("D" & i).Copy: wsForm.Range("H29").PasteSpecial xlPasteValues
.Range("E" & i).Copy: wsForm.Range("E29").PasteSpecial xlPasteValues
.Range("F" & i).Copy: wsForm.Range("D33").PasteSpecial xlPasteValues
.Range("G" & i).Copy: wsForm.Range("K30").PasteSpecial xlPasteValues
.Range("H" & i).Copy: wsForm.Range("P33").PasteSpecial xlPasteValues
.Range("L" & i).Copy: wsForm.Range("H32").PasteSpecial xlPasteValues
.Range("R" & i).Copy: wsForm.Range("D87").PasteSpecial xlPasteValues
'.Range("C5:M5").Copy: wsForm.Range("E102").PasteSpecial xlPasteValues
'~~> Save the form using the value in cell i,B
wbForm.SaveAs .Range("B" & i).Value & ".xls"
wbForm.Close
Set wbForm = Nothing
Set wsForm = Nothing
Next
End With
With wsSource
SecondTable = .Range("B:B").Find("SecondTable").Row
EndTwo = .Range("B" & .Rows.Count).End(xlUp).Row
For i = Second Table + 1 To EndTwo
Set wbForm = Workbooks.Open(formpath) '~~> open the form
Set wsForm = wbForm.Sheets("Processing Form") '~~> Declare which worksheet to activate
'~~> Proceed with the copying / pasting of values
.Range("B" & i).Copy wsForm.Range("F7:K7")
.Range("C" & i).Copy: wsForm.Range("D8").PasteSpecial xlPasteValues
.Range("C" & i).Copy: wsForm.Range("D30").PasteSpecial xlPasteValues
.Range("D" & i).Copy: wsForm.Range("H29").PasteSpecial xlPasteValues
.Range("E" & i).Copy: wsForm.Range("E29").PasteSpecial xlPasteValues
.Range("F" & i).Copy: wsForm.Range("D33").PasteSpecial xlPasteValues
.Range("G" & i).Copy: wsForm.Range("K30").PasteSpecial xlPasteValues
.Range("H" & i).Copy: wsForm.Range("P33").PasteSpecial xlPasteValues
.Range("L" & i).Copy: wsForm.Range("H32").PasteSpecial xlPasteValues
.Range("R" & i).Copy: wsForm.Range("D87").PasteSpecial xlPasteValues
.Range("C5:M5").Copy: wsForm.Range("E102").PasteSpecial xlPasteValues
'~~> Save the form using the cells i,B
wbForm.SaveAs .Range("B" & i).Value & ".xls"
wbForm.Close
Set wbForm = Nothing
Set wsForm = Nothing
Next
End With
End Sub
Am I on the right track with the .Find and a separate copy/paste loop for each table? I realize this is a complex problem and I appreciate any time you take to spend helping me out.
Am I on the right track with the .Find and a separate copy/paste loop for each table?
Not exactly. The code inside those loops is largely the same, so it is a good candidate for subroutine. This will make your code more human-readable, and also makes it easier to maintain since there will only be one place to make revisions, instead of multiple (imagine if you needed to do 10 different iterations, or 1,000 -- you wouldn't possibly write 1,000 different loops to do the same thing!!)
Consider this instead (I observe a few obvious errors which I will correct, but this is not tested). What I have done is to take your several loops, and consolidate them in to a single subroutine. Then we send some information like where the table starts and where it ends, to that subroutine:
Sub CopyStuff(ws as Worksheet, tblStart as Long, tblEnd as Long)
We will send it: wsSource, and the other variables will be used/re-used to determine the start/end of each table. I removed the redundant variables (unless they need to be re-used elsewhere, having two variables EndOne and EndTwo is unnecessary: we can make use of more generic variables like tblStart and tblEnd which we can reassign for subsequent tables.
In this way it is a lot more apparent that we are processing multiple tables in an identical manner. We also have only a single For i = ... loop to manage, should the code require changes in the future. So it is easier to comprehend, and easier to maintain.
Sub CopyToForm()
Dim wbSource As Workbook 'No longer needed in this context: wbForm As Workbook
Dim wsSource As Worksheet 'No longer needed in this context: wsForm As Worksheet
Dim formpath As String, foldertosavepath As String
Dim tblEnd As Long, tblStart As Long, i As Integer
Dim strProcessingFormPath As String
Dim tblStart as Integer: tblStart = 16
Set wbSource = ThisWorkbook '~~> Write your code in Indication Tool.xls
Set wsSource = wbSource.Sheets("Indication Tool") '~~> Put the source sheet name
With wsSource
'~~> Counts how many rows are in the Indication Tool
tblEnd = .Range("B" & .Rows.Count).End(xlUp).Row
If tblEnd < 17 Then GoTo EarlyExit '## I like to use only one exit point from my subroutines/functions
CopyStuff wsSource, tblStart, tblEnd
tblStart = .Range("B:B").Find("SecondTable").Row + 1
tblEnd = .Range("B" & .Rows.Count).End(xlUp).Row
CopyStuff wsSource, tblStart, tblEnd
'And presumably...
tblStart = .Range("B:B").Find("ThirdTable").Row + 1
tblEnd = .Range("B" & .Rows.Count).End(xlUp).Row
CopyStuff wsSource, tblStart, tblEnd
End With
Exit Sub
EarlyExit:
MsgBox "No data for transfer"
End Sub
Private Sub CopyStuff(ws As Worksheet, tblStart as Long, tblEnd as Long)
Dim wbForm as Workbook, wsForm as Worksheet, i As Long
With ws
For i = tblStart to tblEnd
Set wbForm = Workbooks.Open(formpath) '~~> open the form
Set wsForm = wbForm.Sheets("Processing Form") '~~> Declare which worksheet to activate
'~~> Proceed with the copying / pasting of values
.Range("B" & i).Copy wsForm.Range("F7:K7")
.Range("C" & i).Copy: wsForm.Range("D8").PasteSpecial xlPasteValues
.Range("C" & i).Copy: wsForm.Range("D30").PasteSpecial xlPasteValues
.Range("D" & i).Copy: wsForm.Range("H29").PasteSpecial xlPasteValues
.Range("E" & i).Copy: wsForm.Range("E29").PasteSpecial xlPasteValues
.Range("F" & i).Copy: wsForm.Range("D33").PasteSpecial xlPasteValues
.Range("G" & i).Copy: wsForm.Range("K30").PasteSpecial xlPasteValues
.Range("H" & i).Copy: wsForm.Range("P33").PasteSpecial xlPasteValues
.Range("L" & i).Copy: wsForm.Range("H32").PasteSpecial xlPasteValues
.Range("R" & i).Copy: wsForm.Range("D87").PasteSpecial xlPasteValues
'.Range("C5:M5").Copy: wsForm.Range("E102").PasteSpecial xlPasteValues
'~~> Save the form using the value in cell i,B
wbForm.SaveAs .Range("B" & i).Value & ".xls"
wbForm.Close
Set wbForm = Nothing
Set wsForm = Nothing
Next
End With
End Sub