VBA to Copy and Paste Based on Two Criterias - vba

It's is possible to create a macro that do a mathematical sum?
I don't know how to explain. But I already saw another answers but I could not make work for me.
Here is what I trying to do:
I have this Worksheet
iTEM 1 [1]: https://i.stack.imgur.com/v7vXF.jpg
And I to put values as the image below. Make a search and make a mathematical sum in the "available" according with the group.
ITEM 2 [2]: https://i.stack.imgur.com/wQnxu.png
Here would be the result:
ITEM 3 [3]: https://i.stack.imgur.com/ify7J.png

To answer your question, tongue in cheek, Excel is very good at doing mathematical sums, and with the help of VBA it gains versatility. To prove the point, the code below doesn't only act upon your selection in the 'Update' sheet, it takes all the items in the 'Update' sheet and posts them to the 'Database' sheet. Click twice and it's done twice over. There is no break.
Option Explicit
Enum Nup ' Sheet Update
NupFirstDataRow = 2
NupName = 1 ' 1 = column A
NupGroup = 5
NupQty = 7
End Enum
Enum Ndt ' Sheet Data
NdtFirstDataRow = 2
NdtName = 1 ' 1 = column A
NdtGroup = 3
NdtQty ' = 4
NdtOffset = 3 ' NdtGroup + NdtOffset = Group2 column
End Enum
Sub UpdateQuantity()
' 09 Jan 2018
Dim WsUpdate As Worksheet ' Sheet where data are entered
Dim WsData As Worksheet ' Sheet where data are updated
Dim Rng As Range
Dim SearchRng As Range
Dim Itm As String ' an item's name
Dim Qty As Long ' Update quantity (designed for integers)
Dim Rt As Long ' target row in WsData
Dim Rl As Long ' last row in WsUpdate
Dim ClmOffset As Long ' helper
Dim R As Long ' row counter in WsUpdate
Dim Ct As Ndt ' column in WsData
Set WsUpdate = Worksheets("Update")
Set WsData = Worksheets("Database")
With WsData
Rl = .Cells(.Rows.Count, NupName).End(xlUp).Row
Set Rng = Range(.Cells(NdtFirstDataRow, NdtName), .Cells(Rl, NdtQty + NdtOffset))
End With
Application.ScreenUpdating = False
With WsUpdate
Rl = .Cells(.Rows.Count, NupName).End(xlUp).Row
For R = NupFirstDataRow To Rl
Itm = .Cells(R, NupName).Value
Set SearchRng = Range(Rng.Columns(NdtName), Rng.Columns(NdtName))
If CellAddress(Itm, SearchRng, Rt) Then
Itm = .Cells(R, NupGroup).Value
With WsData
Set SearchRng = Range(.Cells(R, NdtGroup), .Cells(R, NdtGroup + NdtOffset))
End With
If CellAddress(Itm, SearchRng, Ct) Then
Qty = Val(.Cells(R, NupQty).Value)
With WsData.Cells(Rt, Ct + 1)
Qty = Val(.Value) + Qty
.Value = Qty
End With
End If
End If
Next R
End With
Application.ScreenUpdating = True
End Sub
Private Function CellAddress(ByVal Itm As String, _
SearchRange As Range, _
Rc As Long) As Boolean
' 09 Jan 2018
' Rc is a return variable (either column or row = 0 if not found)
Dim ClmRng As Range
Dim Fnd As Range
Dim i As Long
With SearchRange
Set Fnd = .Find(What:=Itm, After:=.Cells(.Cells.Count), _
LookIn:=xlValues, LookAt:=xlWhole, _
SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False)
If Fnd Is Nothing Then
Rc = 0
MsgBox "Item """ & Itm & """ wasn't found.", _
vbInformation, "Update failed"
Else
Rc = IIf(.Rows.Count > 1, Fnd.Row, Fnd.Column)
CellAddress = True
End If
End With
End Function
The enumerations at the top of the code control which columns and rows are used. You can modify these numbers. Observe that the quantity columns in the Database must be adjacent to the Group columns. The only other place in the code you may have to change concerns the names of the two worksheets. The code must be in a standard code module in the same workbook.

Related

searching for duplicates

I presently have a UserForm that feeds into a spreadsheet. I require that once the information is entered into the UserForm that a search is done within the spreadsheet for rows that match the same PRI, if so the previous information is deleted and the new information populated in the sheet. It is important that only the matching PRI numbers are removed and if the new submission as additional options than the previous it doesn't overwrite other rows. This is my present coding:
Private Sub CmdAdd_Click()
Dim ws As Worksheet
Dim info
Dim rw As Range
Dim n As Long
Dim r As Range
Const strPwd As String = "Transfer19"
ThisWorkbook.Unprotect Password:=strPwd
Set ws = Worksheets("Inventory")
With ws
'get all the tombstone info into an array
info = Array(Me.TxtFirst.Value, Me.TxtLast.Value, _
Me.TxtPRI.Value, Me.TxtGR.Value, _
Me.TxtLV.Value, Me.TxtLinguistic.Value, _
Me.TxtEmail.Value, Me.TxtResumeNum.Value, _
Me.TxtReason.Value, Me.TxtDate.Value)
.Unprotect Password:="Transfer19"
'get the first empty row...
Set rw = .Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).EntireRow
'loop over the province and city controls
For n = 1 To 10
'get province and city values
p = Me.Controls("ListProv" & n).Value
c = Me.Controls("ListCity" & n).Value
If n = 1 Or p <> "" Then
rw.Cells(1).Resize(1, 10).Value = info
rw.Cells(11).Value = p
rw.Cells(12).Value = c
Set rw = rw.Offset(1, 0)
End If
Next n
.Protect Password:="Transfer19"
End With
ThisWorkbook.Protect Password:=strPwd
ThisWorkbook.Save
End Sub
This is what I tried which partially works. It finds the duplicates and replaces with the new information but it doesn't work with the present loop
'searching for duplicates
Set r = ws.Range("C:C").Find(Me.TxtPRI.Value, LookIn:=xlValues, lookat:=xlWhole)
If Not r Is Nothing Then
MsgBox "Duplicate entry. The record is deleted and the new data is placed"
iRow = r.Row
End If

VBA for find, match and move data

I am trying to find an automated solution for the following daily task.
I have a master workbook with 13 sheets.
Names are Jan-Dec (all 12 months) and Data.
Every sheet has 2 sets of 3 columns: Item Code (A1), Year (B1), Price (C1) and Item Code (E1), Year (F1), Price (G1).
Every day I have over 1000 new entries in "Data" sheet and then have to find matching item code (in Column A) in other 12 sheets, columns A-C, cut and move new matching data to E-G and highlight the new entries.
I tried the following vba code:
Sub TestNewCode()
Application.ScreenUpdating = False
Dim varMainRange As Range
Dim varSubRange As Range
Set varMainRange = Range(Worksheets("Jul").Range("A2:C65536"), _
Worksheets("Jul").Range("A65536").End(xlUp))
For Each MainCell In varMainRange
Set varSubRange = Range(Worksheets("Data").Range("A2"), _
Worksheets("Data").Range("A65536").End(xlUp))
For Each SubCell In varSubRange
If MainCell.Value = SubCell.Value Then
Worksheets("Data").Range("A2:C2").Copy _
Worksheets("Jul").Range("E2:G2")
Exit For
End If
Next SubCell
Next MainCell
Application.ScreenUpdating = True
End Sub
As you can see this code can move only one cell.
I'll appreciate if someone can show a solution to this matter.
I didn't fully test this code, in part because I doubt that you really want to post the data to any of the 12 monthly sheets. Instead, I suspect that the data must be posted to one particular of the monthly sheets. However, that isn't what you said, and therefore my code will look in all sheets and stop looking after it finds a match. This is something you may find easy to adjust. Otherwise I can help you do it.
However, what this code needs now is thorough testing. :-)
Sub TestNewCode()
' 16 Sep 2017
Const Tabs As String = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
Dim WsData As Worksheet
Dim Ws As Worksheet ' any of the monthly sheets
Dim WsName() As String
Dim Rend As Long, Rl As Long ' last row in WsData / Ws
Dim R As Long, Rm As Long ' row counter WsData / Ws
Dim Entry As Variant ' one Data entry
Set WsData = Worksheets("Data")
WsName = Split(Tabs, " ")
Application.ScreenUpdating = False
With WsData
Rend = .Cells(.Rows.Count, "A").End(xlUp).Row
For R = 2 To Rend
Entry = .Range(.Cells(R, 1), .Cells(R, 3)).Value ' A:C
Rm = FindMatch(Entry, Ws, WsName)
If Rm Then ' rm = 0 if not found
With Ws.Cells(Rm, 5).Resize(1, UBound(Entry, 2))
.Value = Entry
.Interior.Color = vbYellow
End With
End If
Next R
End With
Application.ScreenUpdating = True
End Sub
Private Function FindMatch(Entry As Variant, _
Ws As Worksheet, _
WsName() As String) As Long
' return zero if no match was found
Dim Rng As Range ' search range
Dim Fnd As Range
Dim Rl As Long
Dim i As Long
For i = 0 To UBound(WsName)
On Error Resume Next
Set Ws = Worksheets(WsName(i))
If Err Then
MsgBox "Worksheet " & WsName(i) & " doesn 't exist.", _
vbInformation, "Missing worksheet"
Else
With Ws
Rl = .Cells(.Rows.Count, 1).End(xlUp).Row
Set Rng = .Range(.Cells(2, 1), .Cells(Rl, 3))
Set Fnd = Rng.Find(What:=Entry(1, 1), _
After:=Rng.Cells(Rng.Cells.Count), _
LookIn:=xlValues, _
Lookat:=xlWhole, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlNext, _
MatchCase:=False, _
MatchByte:=False)
If Not Fnd Is Nothing Then
FindMatch = Fnd.Row
Exit For
End If
End With
End If
Next i
If Fnd Is Nothing Then
MsgBox "Code " & Entry(1, 1) & " wasn't found.", _
vbInformation, "Missing Code"
End If
End Function

How can I find the last row with a cell containing data vba to set print area?

I know this question may seem nearly identical to past ones, but there's a nuance in my sheet in that one of my columns is completely empty aside from the first 7 rows. The problem being that my code finds the last row in which ALL cells contain data rather than the last row with at least one data item. I.e. A1:Q7 contain data and since all of the rows contain data my code sets the print area to A1:Q7 although there is data in C14. I want my print area to be A1:Q14. How would I go about doing this. Code below.
Sub SetPrintArea()
Dim ALastFundRow As Integer
Dim AFirstBlankRow As Integer
Dim wksSource As Worksheet
Dim ws As Worksheet
Dim rngSheet As Range
Set wksSource = ActiveWorkbook.Sheets("WIRE SCHEDULE")
Set ws = ThisWorkbook.Sheets("WIRE SCHEDULE")
'Finds last row of content
ALastFundRow = wksSource.Range("A8").End(xlDown).Row
'Finds first row without content
AFirstBlankRow = ALastFundRow + 1
Set rngSheet = ws.Range("A1:Q" & LastFundRow + 7)
'Sets PrintArea to the last Column with a value and the last row with a value
ws.PageSetup.PrintArea = rngSheet.Address
End Sub
Anything would help. Thanks!
The function GetLastCell() will find the last row and column containing data
Option Explicit
Public Sub SetPrintArea()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("WIRE SCHEDULE")
ws.PageSetup.PrintArea = ws.Range("A1:" & GetLastCell(ws).Address).Address
End Sub
Public Function GetLastCell(Optional ByVal ws As Worksheet = Nothing) As Range
Dim uRng As Range, uArr As Variant, r As Long, c As Long
Dim ubR As Long, ubC As Long, lRow As Long
If ws Is Nothing Then Set ws = Application.ThisWorkbook.ActiveSheet
Set uRng = ws.UsedRange: uArr = uRng
If IsEmpty(uArr) Then
Set GetLastCell = ws.Cells(1, 1): Exit Function
End If
If Not IsArray(uArr) Then
Set GetLastCell = ws.Cells(uRng.Row, uRng.Column): Exit Function
End If
ubR = UBound(uArr, 1): ubC = UBound(uArr, 2)
For r = ubR To 1 Step -1 '----------------------------------------------- last row
For c = ubC To 1 Step -1
If Not IsError(uArr(r, c)) Then
If Len(Trim$(uArr(r, c))) > 0 Then
lRow = r: Exit For
End If
End If
Next
If lRow > 0 Then Exit For
Next
If lRow = 0 Then lRow = ubR
For c = ubC To 1 Step -1 '----------------------------------------------- last col
For r = lRow To 1 Step -1
If Not IsError(uArr(r, c)) Then
If Len(Trim$(uArr(r, c))) > 0 Then
Set GetLastCell = ws.Cells(lRow + uRng.Row - 1, c + uRng.Column - 1)
Exit Function
End If
End If
Next
Next
End Function
With ActiveSheet 'or whatever worksheet
LastRow = .Cells.Find(what:="*", after:=.Cells(1, 1), _
LookIn:=xlValues, searchorder:=xlByRows, _
searchdirection:=xlPrevious).Row
End With
You can use a similar algorithm for the last column.
LastCol = .Cells.Find(what:="*", after:=.Cells(1, 1), _
LookIn:=xlValues, searchorder:=xlByColumns, _
searchdirection:=xlPrevious).Column
Note that we are looking for xlValues so cells with formulas that return a null string will not be included.
If the worksheet is empty, the code will produce an error; so if that might be a possibility, you should test for that.
Try this code.
.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
Sub SetPrintArea()
Dim ALastFundRow As Integer
Dim AFirstBlankRow As Integer
Dim wksSource As Worksheet
Dim ws As Worksheet
Dim rngSheet As Range
Set wksSource = ActiveWorkbook.Sheets("WIRE SCHEDULE")
Set ws = ThisWorkbook.Sheets("WIRE SCHEDULE")
'Finds last row of content
'ALastFundRow = wksSource.Range("A8").End(xlDown).Row
ALastFundRow = wksSource.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
'Finds first row without content
AFirstBlankRow = ALastFundRow + 1
Set rngSheet = ws.Range("A1:Q" & LastFundRow)
'Sets PrintArea to the last Column with a value and the last row with a value
ws.PageSetup.PrintArea = rngSheet.Address
End Sub

VBA TreeView_NodeCheck: Search for Match in Column and post in row beneath if empty

I am trying to work around the tough task to save selected nodes from a TreeView (tough due to my limited VBA knowledge) by first saving a UserID with a TextBox_AfterUpdate Event and subsequently saving the checked node's full path in the rows below when a match is found. Multiple checks are possible, that's why I approached it the way I did below.
I am working on this Problem for 2 working-days now and pray that one of you can help me out of my misery here haha
No Error is produced and a look at the Debugger Shows me that each column in found correctly. Also, the saving user ID via TextBox_AfterUpdate Event works like a treat and should stay this way. It simply does not copy it - please Help.
Thank you in advance!
Private Sub SuppNo_AfterUpdate()
'########Save SuppNo for CG-entry-saving########
Dim wb As Workbook
Set wb = ActiveWorkbook
Dim ws As Worksheet
Set ws = wb.Worksheets("Supplier Skills")
Dim lastcol As Long
With ws
lastcol = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
'Copy Supplier No into Row 1 and next empty column
ws.Cells(1, lastcol).Offset(0, 1).Value = Me.SuppNo.Value
End Sub
'------------------------------------------------------------------------------------------
Private Sub CGTreeView_NodeCheck(ByVal Node As MSComctlLib.Node)
Dim wb As Workbook
Set wb = ActiveWorkbook
Dim ws As Worksheet
Set ws = wb.Worksheets("Supplier Skills")
Dim myNode As Node
'1. - - Copy Supplier No into Row 1 and next empty column
'Done in SuppNo_Change event
'2.1. - - Find matching entry
Dim aCell As Range
Dim col As Long, lRow As Long, i As Long
Dim colName, NodePath As String
strFind = Me.SuppNo
NodePath = Me.CGTreeView.SelectedItem.FullPath
With ws
Set aCell = .Range("A1:ZZ1").Find(What:=Me.SuppNo, LookIn:=xlValues, LookAt:=xlWhole, _
SearchOrder:=xlByColumns, MatchCase:=False, SearchFormat:=False)
'~~> If Found
If Not aCell Is Nothing Then
col = aCell.Column
colName = Split(.Cells(, col).Address, "$")(1)
lRow = .Range(colName & .Rows.Count).End(xlUp).Row
'2.2. - - Find the last empty row and copy each new FullPath when checked
For i = 2 To 50
If Cells(i, col) Is Nothing Then
ws.Cells(i, col) = NodePath
i = i + 1
End If
Next i
'~~> If not found
Else
Exit Sub
End If
End With
End Sub
I added a few features to eliminate duplicates.
Private Sub SuppNo_AfterUpdate()
'########Save SuppNo for CG-entry-saving########
Dim IDColumn As Long
Dim dItems As Object
Dim c As Range, ItemsRange As Range
Dim n As Node
Set dItems = CreateObject("Scripting.Dictionary")
With ActiveWorkbook.Worksheets("Supplier Skills")
IDColumn = getSuppNoColumn
.Cells(1, IDColumn).Value = Me.SuppNo.Value
Set ItemsRange = .Range(.Cells(2, IDColumn), .Cells(.Rows.count, IDColumn).End(xlUp))
If Not ItemsRange Is Nothing Then
For Each c In ItemsRange
dItems(c.text) = vbNullString
Next
End If
End With
For Each n In CGTreeView.Nodes
n.Checked = dItems.exists(n.FullPath)
Next
End Sub
'------------------------------------------------------------------------------------------
Private Sub CGTreeView_NodeCheck(ByVal Node As MSComctlLib.Node)
Dim IDColumn As Long
Dim dItems As Object
Dim n As Node
If Me.SuppNo.Value <> "" Then
IDColumn = getSuppNoColumn
With ActiveWorkbook.Worksheets("Supplier Skills")
.Range(.Cells(1, IDColumn), .Cells(.Rows.count, IDColumn).End(xlUp)).Offset(1).Clear
Set dItems = CreateObject("Scripting.Dictionary")
For Each n In CGTreeView.Nodes
If n.Checked Then dItems(n.FullPath) = vbNullString
Next
If dItems.count > 0 Then .Cells(2, IDColumn).Resize(dItems.count) = Application.Transpose(dItems.Keys)
End With
End If
End Sub
Function getSuppNoColumn() As Long
Dim f As Range
With ActiveWorkbook.Worksheets("Supplier Skills")
Set f = .Range("1:1").Find(What:=Me.SuppNo, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=False)
If f Is Nothing Then
getSuppNoColumn = IIf(.Cells(1, 1) = "", 1, .Cells(1, .Columns.count).End(xlToLeft).Offset(0, 1).Column)
Else
getSuppNoColumn = f.Column
End If
End With
End Function

Replace a string in Column C based on matching index in Column A

I would appreciate any help on this matter. I am trying to create an Excel 2010 macro in VBA that will read strings in one spreadsheet row by row, and then search another spreadsheet to see if the value exists in a column of strings.
If/When it finds a matching string in column A, I would like to compare the string in column C of the original spreadsheet with the string in Column C of the spreadsheet being searched. If both strings are the same, I would like to move on back to the column A search and continue.
If the strings are different I would like to overwrite the string in Column C of the spreadsheet being searched. I would also like to highlight this change on the searched spreadsheet.
If no matching string is found in column A of the search spreadsheet, then I want to copy the row of the original spreadsheet into the searched spreadsheet and highlight it.
Here's what I have so far, but I can't seem to get it to work properly:
Sub SearchRows()
Dim bottomA1 As Integer
bottomA1 = Sheets("Original Spreadsheet").Range("A" & Rows.Count).End(xlUp).Row
Dim bottomA2 As Integer
bottomA2 = Sheets("Searched Spreadsheet").Range("A" & Rows.Count).End(xlUp).Row
Dim rng1 As Range
Dim rng2 As Range
Dim x As Long
Dim y As Long
Dim foundColumnA As Range
Dim foundColumnC As Range
For Each rng1 In Sheets("Original Spreadsheet").Range("A2:A" & bottomA1)
With Sheets("Searched Spreadsheet").Range("A2:A" & bottomA2)
Set foundColumnA = .Find(what:=rng1, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
For Each rng2 In Sheets("Original Spreadsheet").Range("E2:E" & bottomA1)
With Sheets("Searched Spreadsheet").Range("E2:E" & bottomA2)
Set foundSize = .Find(what:=rng2, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=True)
If foundColumnC Is Nothing Then
bottomE2 = Sheets("Column C Changes").Range("E" & Rows.Count).End(xlUp).Row
y = bottomA2 + 1
rng2.EntireRow.Copy Sheets("Column C Changes").Cells(y, "A")
Sheets("Column C Changes").Cells (y, "A").EntireRow.Interior.ColorIndex = 4
End If
End With
Next rng2
If foundTag Is Nothing Then
bottomA2 = Sheets("Column A Changes").Range("A" & Rows.Count).End(xlUp).Row
x = bottomA2 + 1
rng1.EntireRow.Copy Sheets("Column A Changes").Cells(x, "A")
Sheets("Column A Changes").Cells(x, "A").EntireRow.Interior.ColorIndex = 3
End If
End With
Next rng1
End Sub
You actually have too much code, but they're not set up cleanly. Qualify a lot of things as much as possible so it's cleaner, and try to be consistent with your style. This way you can identify the error as much as possible.
Anyway, on to the code. The basic logic you want is as follows, based on the details above:
Check if a string in Sheet1!A is in Sheet2!A.
If found, compare Column C values.
If Column C values are different, set value of Sheet2 to that in Sheet1 and highlight.
Else, exit.
If not found, copy whole row to Sheet2 and highlight.
Now that we have that written down, it's simpler! :)
Please check my screenshots for my set-up:
SCREENSHOTS:
Sheet1:
Sheet2:
Note that for Sheet2, I don't have BK207 onwards. ;) Now, onto the code.
CODE:
Sub LoopMatchReplace()
Dim ShSrc As Worksheet, ShTar As Worksheet
Dim SrcLRow As Long, TarLRow As Long, NextEmptyRow As Long
Dim RefList As Range, TarList As Range, RefCell As Range, RefColC
Dim TarCell As Range, TarColC As Range
Dim IsFound As Boolean
Dim ToFind As String
With ThisWorkbook
Set ShSrc = .Sheets("Sheet1")
Set ShTar = .Sheets("Sheet2")
End With
'Get the last rows for each sheet.
SrcLRow = ShSrc.Range("A" & Rows.Count).End(xlUp).Row
TarLRow = ShTar.Range("A" & Rows.Count).End(xlUp).Row
'Set the lists to compare.
Set RefList = ShSrc.Range("A2:A" & SrcLRow)
Set TarList = ShTar.Range("A2:A" & TarLRow)
'Initialize boolean, just for kicks.
IsFound = False
'Speed up the process.
Application.ScreenUpdating = False
'Create the loop.
For Each RefCell In RefList
ToFind = RefCell.Value
'Look for the value in our target column.
On Error Resume Next
Set TarCell = TarList.Find(ToFind)
If Not TarCell Is Nothing Then IsFound = True
On Error GoTo 0
'If value exists in target column...
If IsFound Then
'Compare the Column C of both sheets.
Set TarColC = TarCell.Offset(0, 2)
Set RefColC = RefCell.Offset(0, 2)
'If they are different, set the value to match and highlight.
If TarColC.Value <> RefColC.Value Then
TarColC.Value = RefColC.Value
TarColC.Interior.ColorIndex = 4
End If
Else 'If value does not exist...
'Get next empty row, copy the whole row from source sheet, and highlight.
NextEmptyRow = ShTar.Range("A" & Rows.Count).End(xlUp).Row + 1
RefCell.EntireRow.Copy ShTar.Rows(NextEmptyRow)
ShTar.Rows(NextEmptyRow).SpecialCells(xlCellTypeConstants).Interior.ColorIndex = 3
End If
'Set boolean check to False.
IsFound = False
Next RefCell
Application.ScreenUpdating = True
End Sub
Kindly read the comments for the codeblocks so you get an understanding of what I'm doing. Also, note the way that I have qualified everything and properly set them up in a very clean way. Clean code is 50% good code.
Check the following screenshot to see the results after running the code.
END RESULT:
Note the added rows at the end and the changed values in Column C. I did not have the whole row highlighted as I believe that's bad practice and messy, but it's up to you to change the respective lines and values to suit your taste for the end result.
Let us know if this helps.
I think you can use this code.
Values not found will be added to the end of destination sheet.
Differences are signed with a blue(change if you want) background color.
Sub copy_d()
Dim r1 As Long, rfound, vfound
Dim w1, w2, v, lastR As Long, lastC As Long
Set w1 = Sheets("sheet1") ' change the origin sheet at will
Set w2 = Sheets("sheet2") ' change the destination sheet at will
r1 = 1 ' assuming data start in row 1, change it if not
Do While Not IsEmpty(w1.Cells(r1, 1))
v = w1.Cells(r1, 1)
rfound = Application.Match(v, w2.Columns(1), 0) ' look for value
If Not IsError(rfound) Then ' found it?
vfound = w2.Cells(rfound, 3)
If w1.Cells(r1, 3) <> vfound Then ' value in column C is different?
w2.Cells(rfound, 3) = w1.Cells(r1, 3) ' update based on origin sheet
lastC = w2.Cells(rfound, 1).End(xlToRight).Column
w2.Range(w2.Cells(rfound, 1), w2.Cells(rfound, lastC)).Interior.ColorIndex = 5
End If
Else
lastR = w2.Cells(1, 1).End(xlDown).Row + 1
w1.Rows(r1).copy Destination:=w2.Rows(lastR) ' copy to last row of dest sheet
lastC = w2.Cells(lastR, 1).End(xlToRight).Column
w2.Range(w2.Cells(lastR, 1), w2.Cells(lastR, lastC)).Interior.ColorIndex = 5
End If
r1 = r1 + 1
Loop
End Sub