VBA Excel Macro not responding after execution - excel

I am trying to import data from Report file to my workbook file. Also to do it automatically with different files with new data, so that I can update my rows in the workbook file. The code opens the Report file after executing but it is not responding.
Sub Weekly_Report()
Path = "C:\Users\Documents\Report"
Filename = Dir(Report & "*.xlsx")
Do While Filename <> ""
Workbooks.Open Filename:=Path & Report, ReadOnly:=True
Loop
Dim starting_row As Long
header_exists = True 'If the file has a header and you don't want to import it, set this to True
starting_row = 1
If header_exists Then starting_row = 2
Dim first_blank_row As Long
first_blank_row = Cells.SpecialCells(xlCellTypeLastCell).Offset(1, 0).Row 'Finds the last blank row
Dim r As Long
r = starting_row
Dim Filenames As String
Filenames = Path
Dim found As Range
Row = Workbooks(Filenames).ActiveSheet.Range("a" & r).Value
Do While Not Row = ""
Set found = Columns("x:x").Find(what:=Row, LookIn:=xlValues, lookat:=xlWhole)
If found Is Nothing Then
write_line_from_export Filenames, r, first_blank_row
first_blank_row = first_blank_row + 1
Else
write_line_from_export Filenames, r, found.Row
End If
r = r + 1
Row = Workbooks(Filenames).ActiveSheet.Range("a" & r).Value
Loop
End Sub
Sub write_line_from_export(Filenames As String, s As Long, d As Long)
For e = 1 To 69
Cells(d, e).Value = Workbooks(Filenames).ActiveSheet.Cells(s, e).Value
Next e
End Sub

Try this:
Sub Weekly_Report()
Const HAS_HEADER As Boolean = True '<< use contants for fixed values
Const NUM_COLS As Long = 69
Dim Path, Filename, wbReport As Workbook, wsReport As Worksheet, m
Dim wsData As Worksheet, next_blank_row As Long, r As Long, c As Range, rwStart As Long
Path = "C:\Users\Documents\Report\"
Filename = Dir(Path & "Report*.xlsx") '???
Set wsData = ThisWorkbook.Worksheets("Data") 'for example: destination worksheet
next_blank_row = next_blank_row = wsData.Cells(Rows.Count, 1).End(xlUp).Row + 1 'next blank row (edited)
'make sure row is really empty...
Do While Application.CountA(wsData.Rows(next_blank_row)) > 0
next_blank_row = next_blank_row + 1
Loop
Do While Filename <> ""
Set wbReport = Workbooks.Open(Path & Filename) '<< get a reference to the workbook
Set wsReport = wbReport.Worksheets(1) '<< assumes only one sheet
rwStart = IIf(HAS_HEADER, 2, 1)
For r = rwStart To wsReport.Cells(Rows.Count, 1).End(xlUp).Row
'Match is faster than Find
m = Application.Match(wsReport.Cells(r, 1).Value, wsData.Columns("X"), 0)
If IsError(m) Then
m = next_blank_row 'no match - use next blank row and increment
next_blank_row = next_blank_row + 1
End If
'don't go cell-by-cell
wsData.Cells(m, 1).Resize(1, NUM_COLS).Value = _
wsReport.Cells(r, 1).Resize(1, NUM_COLS).Value
Next r
wbReport.Close False
Filename = Dir()
Loop
End Sub

Related

Comparing first sheet to second sheet name, if name matched in second sheet then insert the row into the first sheet based on name

I have two workbooks that have different column structures. I want to compare names from the "studentMaster" sheet and "wpl" sheet, if the name matched in "wpl" then copy the row value and insert it into the "studentMaster" sheet.
My code:
Sub findWPLMarks()
'Declare the workbook
Dim studMaster As Workbook, WPL_Result As Workbook
'Destination sheets
Dim MstdataSh As Worksheet, wplSh As Worksheet
'Declare the variables
Dim i As Long, j As Long, foundrow As Long, rowInc As Long, colInc As Long
Dim lastrow1 As Long, lastrow2 As Long, lastcol As Long
Dim mstFName As String, WPLFName As String
Dim WPLfldName As String, folderPath() As String
'Declare the path value
mstFName = Range("C15").Value
WPLFName = Range("B9").Value
'Split the file name path
folderPath = Split(WPLFName, Application.PathSeparator)
WPLfldName = folderPath(4)
'Set Workbook
Set studMaster = Workbooks.Open(mstFName)
Set WPL_Result = Workbooks.Open(WPLFName)
'Master sheet
Set MstdataSh = studMaster.Sheets("StudentDetails") 'ws2
'Destination sheet
Set wplSh = WPL_Result.Sheets("WPL") 'ws1
Application.ScreenUpdating = False
lastrow1 = MstdataSh.Cells(MstdataSh.Rows.Count, "A").End(xlUp).Row
lastrow2 = wplSh.Cells(wplSh.Rows.Count, "A").End(xlUp).Row
lastcol = MstdataSh.Cells(6, MstdataSh.Columns.Count).End(xlToLeft).Column
Debug.Print (lastcol)
rowInc = 7
For i = 1 To lastrow1
colInc = 4
On Error Resume Next
foundrow = wplSh.Range("A2:A" & lastrow2).Find(MstdataSh.Cells(i, 4).Value).Row
'foundrow = MstdataSh.Range("D7:D" & lastrow1).Find(wplSh.Cells(i, 1).Value).Row
If Err.Number = 91 Then
' ws3.Cells(i, 1) = ws1.Cells(i, 1)
'MstdataSh.Cells(i, 1) = wplSh.Cells(i, 1)
'Debug.Print wplSh.Cells(i, 1)
Else
For j = 1 To lastrow2
'ws3.Cells(i, j) = ws2.Cells(foundrow, j)
MstdataSh.Cells(foundrow, colInc) = wplSh.Cells(foundrow, j)
colInc = colInc + 3
Next j
End If
rowInc = rowInc + 1
Next i
'Close workbook
studMaster.Close savechanges:=True
WPL_Result.Close savechanges:=True
'ActiveWorkbook.Close savechanges:=False
Application.ScreenUpdating = True
End Sub
If the Assessment Date is different for the duplicate students' in the "wpl" sheet then need to select the best value for each column for that student.
Could you help me insert the row into the "studentMaster" sheet?

Copy and pasting to a template and saving as new workbook

I'm trying to loop through and paste each different group of IDs into a template I have in a separate workbook. I then want it to save as a new workbook, using the Vendor Name in C1 of the second sheet in the new workbook.
But there's a few problems in me trying to complete this;
It is giving me an error at the SaveAs line.
The filename is not pulling from the cell I want.
It stops after the first loop.
Anybody have any ideas of what I need to fix?
Here is my current macro:
Option Explicit
SubNewBillback()
Dim wsBData, wsBackup, wsCreditMemo As Worksheet
Dim wb, wbTemplate, wbAllRebates As Workbook
Dim rngHeader As Range
Dim i As Long, n As Long, LastRow As Long, StartRow As Long
Dim InvNum, InvDate, VendName, VendNum, strPath, FileName, openfile As String
Dim Amt As Integer
strPath = "\\Billback Data Base-Spreadsheet\2021\September\Excel\"
openfile = "\\Billback Data Base-Spreadsheet\2021\September\BillbackAutoTemplate.xlsx"
Set wbAllRebates = ActiveWorkbook
With wbAllRebates
Set wsBData = .Sheets("BackupData")
Set wsBackup = .Sheets("Backup")
End With
'copy data from query
wsBData.Cells.Copy
wsBackup.Cells.PasteSpecial Paste:=xlPasteValues
StartRow = 2
Application.ScreenUpdating = False
'searches for change in ID#
With wsBackup
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
Set rngHeader = .Range("A1:O1")
For i = 2 To LastRow
' change ID next row
If .Cells(i, "A") <> .Cells(i + 1, "A") Then
' create new workbook
Set wbTemplate = Workbooks.Open(openfile)
.Range("A" & StartRow & ":O" & i).Copy wbTemplate.Sheets(2).Range("A2")
wbTemplate.SaveAs FileName:=strPath & Sheets(2).Cells(i, "C") & ".xlsx"
wbTemplate.Close True
' move to next
StartRow = i + 1
n = n + 1
End If
Next
End With
Application.ScreenUpdating = True
MsgBox n & " billbacks created."
End Sub
The function at the bottom will remove invalid characters from your file name. I've added the call to the function in your Save As line in your original code. It will replace any of the following characters in the vendor name : \ / ? | * [ ] { } < > ~ " # % & with a _. If you would rather it replace it with something else just change the "_" in the line sFileName = Replace(sFileName, Mid(vInval, i, 1), "_") to some other valid character
Option Explicit
Sub NewBillback()
Dim wsBData, wsBackup, wsCreditMemo As Worksheet
Dim wb, wbTemplate, wbAllRebates As Workbook
Dim rngHeader As Range
Dim i As Long, n As Long, LastRow As Long, StartRow As Long
Dim InvNum, InvDate, VendName, VendNum, strPath, FileName, openfile As String
Dim Amt As Integer
strPath = "\\Billback Data Base-Spreadsheet\2021\September\Excel\"
openfile = "\\Billback Data Base-Spreadsheet\2021\September\BillbackAutoTemplate.xlsx"
Set wbAllRebates = ActiveWorkbook
With wbAllRebates
Set wsBData = .Sheets("BackupData")
Set wsBackup = .Sheets("Backup")
End With
'copy data from query
wsBData.Cells.Copy
wsBackup.Cells.PasteSpecial Paste:=xlPasteValues
StartRow = 2
Application.ScreenUpdating = False
'searches for change in ID#
With wsBackup
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
Set rngHeader = .Range("A1:O1")
For i = 2 To LastRow
' change ID next row
If .Cells(i, "A") <> .Cells(i + 1, "A") Then
' create new workbook
Set wbTemplate = Workbooks.Open(openfile)
.Range("A" & StartRow & ":O" & i).Copy wbTemplate.Sheets(2).Range("A2")
wbTemplate.SaveAs FileName:=strPath & ValidateFileName(Sheets(2).Cells(i, "C")) & ".xlsx"
wbTemplate.Close True
' move to next
StartRow = i + 1
n = n + 1
End If
Next
End With
Application.ScreenUpdating = True
MsgBox n & " billbacks created."
End Sub
Function ValidateFileName(ByVal sFileName As String) As String
Dim vInval As String
Dim i As Long
vInval = ":\/?|*[]{}<>~""#%&" & Chr(10) & Chr(13)
For i = 1 To Len(vInval)
sFileName = Replace(sFileName, Mid(vInval, i, 1), "_")
Next i
ValidateFileName = sFileName
End Function

Loop through 50,000+ rows and copy data until value in the first column changes

I have an Excel sheet with 50,000+ rows of data from A:N. I have a Master Data Sheet that has a query in the BackupData worksheet. I currently copy that data and paste as values into the Backup worksheet. With the headers:
ID
Vendor #
Name
Customer #
Customer
Invoice #
Date
Item#
Item Description
Qty
B/C
Lbs
Amt
Amt#2
I am trying to loop through all of these rows and copy the range of cells A:N until the first value change in Column A, the first different ID #.
I then need to paste the selected range into a new workbook.
Basically, I want to do the opposite of consolidating.
Sub inserting()
Dim wsBData, wsExport, wsCoverSht, wsBackup As Worksheet
Dim wbAllRebates, wbSingle As Workbook
Set wbAllRebates = ActiveWorkbook
Set wsBData = wbAllRebates.Sheets("BackupData")
Set wsBackup = wbAllRebates.Sheets("Backup")
Dim rID, rTopRow As Range
Dim i As Long
Dim Counter As Integer
i = 3
Set rTopRow = Rows(1)
Set rID = wsBackup.Range("A1")
wsBData.Cells.Copy
wsBackup.Cells.PasteSpecial Paste:=xlPasteValues
Counter = 0
LastRow = ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row
Do
If rID.Offset(i).Value <> rID.Offset(i - 1).Value Then
Rows(rID.Offset(i).Row).Insert shift:=xlDown
Call SubTotals(rID.Offset(i), rTopRow)
i = i + 1
Set rTopRow = Rows(rID.Offset(i).Row)
End If
Exit Do
Loop
MsgBox i
End Sub
Sub SubTotals(rID As Range, firstRow As Range)
rID.Value = "Total"
rID.Offset(, 9).Value = Application.WorksheetFunction.Sum(Range(firstRow.Cells(1, 10).Address & ":" & rID.Offset(-1, 1).Address))
End Sub
Try
Option Explicit
Sub SeparateWB()
Dim wsBData As Worksheet, wsBackup As Worksheet, wb As Workbook
Dim wbAllRebates As Workbook, rngHeader As Range
Dim i As Long, n As Long, LastRow As Long, StartRow As Long
Set wbAllRebates = ActiveWorkbook
With wbAllRebates
Set wsBData = .Sheets("BackupData")
Set wsBackup = .Sheets("Backup")
End With
wsBData.Cells.Copy
wsBackup.Cells.PasteSpecial Paste:=xlPasteValues
StartRow = 2
Application.ScreenUpdating = False
With wsBackup
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
Set rngHeader = .Range("A1:N1")
For i = 2 To LastRow
' change ID next row
If .Cells(i, "A") <> .Cells(i + 1, "A") Then
' create new workbook
Set wb = Workbooks.Add(1)
rngHeader.Copy wb.Sheets(1).Range("A1")
.Range("A" & StartRow & ":N" & i).Copy wb.Sheets(1).Range("A2")
wb.SaveAs .Cells(i, "A") & ".xlsx"
wb.Close False
' move to next
StartRow = i + 1
n = n + 1
End If
Next
End With
Application.ScreenUpdating = True
MsgBox n & " workbooks created"
End Sub

Find all matches in workbook and offset the results into another sheet (VBA)

I'd like some help if possible! Currently, it's causing the excel sheet to crash each time it runs, perhaps because the loop is not ending. Could anyone try helping me fix my code? All 4 sheets have under 5000 rows.
I currently have a workbook with 4 sheets(the number of sheets will change) and one more sheet called Results.
I have managed to look for the string: "Employee Code:-" in Column B, and get the value in Column Y and Column K and paste it in Results A and B respectively. (starting in the 5th row of the Results sheet). (Moving to the next find if Column S and Column K have the same value).
I then would need the values from 3 and 4 rows below the "Employee Code" running from D to AN and pasting it alongside the values from S and K
Then leaving a line after the results have been pasted and repeating for the rest of the find values.
Sub FindAndExecute()
Dim Sh As Worksheet
Dim Loc As Range
Dim i,j As Integer
i = 5
For Each Sh In ThisWorkbook.Worksheets
With Sh.UsedRange
Set Loc = .Cells.Find(What:="Employee Code:-")
If Not Loc Is Nothing Then
Do Until Loc Is Nothing
If Loc.Offset(0, 9).Value <> Loc.Offset(0, 23).Value Then
Sheets("Result2").Cells(i, 1).Value = Loc.Offset(0, 9).Value
Sheets("Result2").Cells(i, 2).Value = Loc.Offset(0, 23).Value
j = 3
Do
Sheets("Result2").Cells(i, j).Value = Loc.Offset(3, j - 1).Value
Sheets("Result2").Cells(i + 1, j).Value = Loc.Offset(4, j -
1).Value
j = j + 1
Loop Until j > 35
i = i + 3
Else
End If
Set Loc = .FindNext(Loc)
Loop
End If
End With
Set Loc = Nothing
Next
End Sub
With FindNext check the search hasn't started again from the beginning.
Sub FandAndExecute2()
Const TEXT = "Employee Code:-"
Const COL_CODE = 2 ' B
Const COL_Y = 25 ' Y
Const COL_K = 11 ' K
' copy from
Const COL_START = "D"
Const COL_END = "AM"
' copy to
Const TARGET = "Result2"
Const START_ROW = 5
Dim wb As Workbook, ws As Worksheet, wsResult As Worksheet
Dim rng As Range, rngSearch As Range, rngCopy As Range
Dim r As Long, iLastRow As Long, iTarget As Long
Dim sFirstFind As String, K, Y, n As Integer
Set wb = ThisWorkbook
Set wsResult = wb.Sheets(TARGET)
iTarget = START_ROW
' scan sheets
For Each ws In wb.Sheets
If ws.Name = TARGET Then GoTo skip
iLastRow = ws.Cells(Rows.Count, COL_CODE).End(xlUp).Row
Set rngSearch = ws.Cells(1, COL_CODE).Resize(iLastRow)
' search for text
With rngSearch
Set rng = .Find(TEXT, LookIn:=xlValues)
If Not rng Is Nothing Then
sFirstFind = rng.Address
Do
r = rng.Row
K = ws.Cells(r, COL_K)
Y = ws.Cells(r, COL_Y)
If K <> Y Then
' copy block
wsResult.Cells(iTarget, "A").Value = K
wsResult.Cells(iTarget, "B").Value = Y
Set rngCopy = ws.Range(COL_START & r + 3 & ":" & COL_END & r + 4)
rngCopy.Copy wsResult.Cells(iTarget, "C")
iTarget = iTarget + 3
n = n + 1
End If
Set rng = .FindNext(rng) ' find next
Loop While Not rng Is Nothing And rng.Address <> sFirstFind
End If
End With
skip:
Next
MsgBox n & " blocks copied to " & wsResult.Name, vbInformation
End Sub

Excel Macro updating rows in a file with new data

The code below runs and executes perfectly, I just want to add some features. The code imports the new rows from Report file to Workbook file, and I want it to check for a potential row with new data by every cell in the row, and not by just column G(contains number or numbers separated by comma), but in range A2:BQ. Also update the newly found cells even if the row exists in Workbook by the number in column G. Also to highlight the new rows with a bright color in the Workbook file. One last thing is to wrap the text after the importing of new cells finishes.
Sub Weekly_Report()
Const HAS_HEADER As Boolean = True 'Set true if the file has a header(Report)
Const NUM_COLS As Long = 69 '69 rows needed to be imported from the Report
Const FILENAME = "Report.xlsx"
Const PATH = "C:\Users\Documents\" 'path of the report
Dim wbReport As Workbook, wsReport As Worksheet, wsData As Worksheet
Dim next_blank_row As Long, iStartRow As Long, iLastRow As Long, iRow As Long
Dim sFilename As String
Set wsData = ThisWorkbook.Worksheets("Sheet1") 'for example: destination worksheet
next_blank_row = wsData.Cells(Rows.Count, "G").End(xlUp).Row + 1 'next blank row
sFilename = PATH & FILENAME
Debug.Print "Opening ", sFilename 'Openning file
On Error Resume Next
Set wbReport = Workbooks.Open(sFilename)
On Error GoTo 0
If wbReport Is Nothing Then
MsgBox "Can not open " & sFilename, vbCritical, "ERROR" 'If the file was not found or cannot be opened
Exit Sub
End If
Set wsReport = wbReport.Worksheets(1) 'Expects only one sheet in the Report
iStartRow = IIf(HAS_HEADER, 2, 1) 'If it has header start from row 2
iLastRow = wsReport.Cells(Rows.Count, 1).End(xlUp).Row
Dim s As String, rng As Range, m As Long
For iRow = iStartRow To iLastRow
s = CStr(wsReport.Cells(iRow, "G").Value)
Set rng = wsData.Columns("A:BQ").Find(s)
If rng Is Nothing Then
m = next_blank_row 'no match - use next blank row and increment
next_blank_row = next_blank_row + 1
Debug.Print iRow, s, "New row " & m
Else
m = rng.Row
Debug.Print iRow, s, "Match row " & m 'Match row:if the line already exists in the file
End If
wsData.Cells(m, 1).Resize(1, NUM_COLS).Value = wsReport.Cells(iRow, 1).Resize(1, NUM_COLS).Value 'Put the new line in Workbook
Next
MsgBox wsReport.Name & " scanned from row " & iStartRow & _
" to " & iLastRow, vbInformation, sFilename
wbReport.Close False 'Close the Report
End Sub
This updates column P and S for rows matching column G or adds the rows if no match.
Option Explicit
Sub Weekly_Report()
Const HAS_HEADER As Boolean = True 'Set true if the file has a header(Report)
Const NUM_COLS As Long = 69 '69 cells in the row needed to be imported from the Report
Const FILENAME = "Report.xlsx"
Const PATH = "C:\Users\Documents\" 'path of the report
Dim wbReport As Workbook, wsReport As Worksheet, wsData As Worksheet
Dim next_blank_row As Long, iStartRow As Long, iLastRow As Long, iRow As Long
Dim sFilename As String
Set wsData = ThisWorkbook.Worksheets("Sheet1") 'for example: destination worksheet
next_blank_row = wsData.Cells(Rows.Count, "G").End(xlUp).Row + 1 'next blank row
sFilename = PATH & FILENAME
Debug.Print "Opening ", sFilename 'Openning file
On Error Resume Next
Set wbReport = Workbooks.Open(sFilename)
On Error GoTo 0
If wbReport Is Nothing Then
MsgBox "Can not open " & sFilename, vbCritical, "ERROR" 'If the file was not found or cannot be opened
Exit Sub
End If
Set wsReport = wbReport.Worksheets(1) 'Expects only one sheet in the Report
iStartRow = IIf(HAS_HEADER, 2, 1) 'If it has header start from row 2
iLastRow = wsReport.Cells(Rows.Count, 1).End(xlUp).Row
Dim rng As Range, rng2 As Range, rng3 As Range
Dim m As Long, m2 As String, m3 As String, s As String, s2 As String, s3 As String, c As Variant
Dim iAdd As Long, iUpdate As Long
For iRow = iStartRow To iLastRow
s = CStr(wsReport.Cells(iRow, "G").Value)
Set rng = wsData.Columns("G").Find(s)
If rng Is Nothing Then
m = next_blank_row 'no match - use next blank row and increment
next_blank_row = next_blank_row + 1
With wsData.Cells(m, 1).Resize(1, NUM_COLS)
.Value = wsReport.Cells(iRow, 1).Resize(1, NUM_COLS).Value
.Interior.Color = vbYellow
End With
iAdd = iAdd + 1
Debug.Print iRow, s, "New row " & m
Else
m = rng.Row
For Each c In Array("P", "S")
If wsData.Cells(m, c) <> CStr(wsReport.Cells(iRow, c).Value) Then
wsData.Cells(m, c) = CStr(wsReport.Cells(iRow, c).Value)
wsData.Cells(m, c).Interior.Color = vbGreen
iUpdate = iUpdate + 1
End If
Next
Debug.Print iRow, s, "Match row " & m 'Match row:if the line already exists in the file
End If
Next
MsgBox wsReport.Name & " scanned from row " & iStartRow & _
" to " & iLastRow & vbCrLf & "added rows = " & iAdd & vbCrLf & _
"updated cells = " & iUpdate, vbInformation, sFilename
wbReport.Close False 'Close the Report
End Sub
Since you seem to be stuck on comparing two ranges:
'Do two ranges contain the same value(s)?
' does not handle error values...
Function RangesMatch(rng1 As Range, rng2 As Range) As Boolean
Dim rv As Boolean, v1, v2, r As Long, c As Long
If rng1.Rows.Count = rng2.Rows.Count And _
rng1.Columns.Count = rng2.Columns.Count Then
v1 = rng1.Value
v2 = rng2.Value
If rng1.Count = 1 Then
RangesMatch = (v1 = v2) 'single cell ranges...
Else
'multi-cell ranges: loop and compare values
For r = 1 To UBound(v1, 1)
For c = 1 To UBound(v1, 2)
If v1(r, c) <> v2(r, c) Then
Exit Function 'by default returns false
End If
Next c
Next r
RangesMatch = True
End If
End If
End Function
This is how far I got:
Sub Weekly_Report()
Const HAS_HEADER As Boolean = True 'Set true if the file has a header(Report)
Const NUM_COLS As Long = 69 '69 cells in the row needed to be imported from the Report
Const FILENAME = "Report.xlsx"
Const PATH = "C:\Users\Documents\" 'path of the report
Dim wbReport As Workbook, wsReport As Worksheet, wsData As Worksheet
Dim next_blank_row As Long, iStartRow As Long, iLastRow As Long, iRow As Long
Dim sFilename As String
Set wsData = ThisWorkbook.Worksheets("Sheet1") 'for example: destination worksheet
next_blank_row = wsData.Cells(Rows.Count, "G").End(xlUp).Row + 1 'next blank row
sFilename = PATH & FILENAME
Debug.Print "Opening ", sFilename 'Openning file
On Error Resume Next
Set wbReport = Workbooks.Open(sFilename)
On Error GoTo 0
If wbReport Is Nothing Then
MsgBox "Can not open " & sFilename, vbCritical, "ERROR" 'If the file was not found or cannot be opened
Exit Sub
End If
Set wsReport = wbReport.Worksheets(1) 'Expects only one sheet in the Report
iStartRow = IIf(HAS_HEADER, 2, 1) 'If it has header start from row 2
iLastRow = wsReport.Cells(Rows.Count, 1).End(xlUp).Row
Dim s As String, rng As Range, m As Long, m2 As String, m3 As String, s2 As String, s3 As String, rng2 As Range, rng3 As Range
For iRow = iStartRow To iLastRow
s = CStr(wsReport.Cells(iRow, "G").Value)
Set rng = wsData.Columns("G").Find(s)
s2 = CStr(wsReport.Cells(iRow, "P").Value)
Set rng2 = wsData.Columns("P").Find(s2)
s3 = CStr(wsReport.Cells(iRow, "S").Value)
Set rng3 = wsData.Columns("S").Find(s3)
If rng Is Nothing Then
m = next_blank_row 'no match - use next blank row and increment
next_blank_row = next_blank_row + 1
Debug.Print iRow, s, "New row " & m
Else
m = rng.Row
Debug.Print iRow, s, "Match row " & m 'Match row:if the line already exists in the file
m2 = rng2.Row
m3 = rng3.Row
End If
wsData.Cells(m, 1).Resize(1, NUM_COLS).Value = wsReport.Cells(iRow, 1).Resize(1, NUM_COLS).Value
wsData.Cells(m2, 1).Resize(1, NUM_COLS).Value = wsReport.Cells(iRow, 1).Resize(1, NUM_COLS).Value
wsData.Cells(m3, 1).Resize(1, NUM_COLS).Value = wsReport.Cells(iRow, 1).Resize(1, NUM_COLS).Value
Next
MsgBox wsReport.Name & " scanned from row " & iStartRow & _
" to " & iLastRow, vbInformation, sFilename
wbReport.Close False 'Close the Report
End Sub

Resources