I want to ask couple of Qs.
1.
Code below dynamically add new rows before the cell that contain "7000"
Code works but it is not very efficient. It slows down where I used For Next loop to insert new rows. Is there better way to insert rows dynamically before cell that contain "7000".
Sub PLFinalReport()
Dim XCount As Integer
Dim YCount As Integer
Dim i As Integer
JobsPivot.Activate
XCount = JobsPivot.Range("H3", Range("H3").End(xlDown)).Count
PLJob.Activate
Range("G6", Range("G6").End(xlDown)).Find("7000").Select
YCount = Range(ActiveCell, ActiveCell.End(xlUp)).Count - 2
For i = 1 To (XCount - YCount)
ActiveCell.EntireRow.Insert
Next i
JobsPivot.Activate
JobsPivot.Range("H3", Range("H3").End(xlDown).End(xlToRight)).Copy
PLJob.Range("G6").PasteSpecial
End Sub
Also I want to copy the forumulas from cell B444 to F44 and paste them all the way down to the last row containing formulas. Same way as we do in the excel with fill handle.
Thanks
Please try this code.
Sub PLFinalReport()
' 13 Feb 2018
Dim SourceRange As Range
Dim TargetRange As Range
Dim R As Long
Dim C As Long
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
Set SourceRange = JobsPivot.Range("H3")
With SourceRange
C = .End(xlToRight).Column - .Column + 1
Set SourceRange = .Resize((.End(xlDown).Row - .Row + 1), C)
End With
C = 7 ' Column G
With PLJob
R = MatchRow("7000", .Cells(6, C)) ' = G6
If R Then
Set TargetRange = Range(.Cells(R, C), .Cells((R + SourceRange.Rows.Count - 1), C))
TargetRange.Rows.EntireRow.Insert
SourceRange.Copy .Cells(R, "H") ' column H
Else
' "7000" wasn't found
End If
End With
With Application
.Calculation = xlCalculationAutomatic
.ScreenUpdating = True
End With
End Sub
Private Function MatchRow(ByVal Crit As Variant, _
ByVal StartCell As Range) As Long
' 13 Feb 2018
Dim Rng As Range
Dim Rl As Long
Dim Fnd As Range
With StartCell.Worksheet
Rl = .Cells(.Rows.Count, 1).End(xlUp).Row ' find last used row
Set Rng = Range(.Cells(StartCell.Row, StartCell.Column), _
.Cells(Rl, StartCell.Column))
End With
With Rng
Set Fnd = .Find(What:=Crit, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
End With
On Error Resume Next
MatchRow = Fnd.Row
End Function
I was more careful with the Find function because there are many reasons why the item might not be found causing an "unexplained" crash. One of the reasons is that Excel remembers most of the settings of your last use of Find. If your code doesn't make clear which settings to use you may not always get the same result with the same code. Consider the setting of the LookAt property in this regard.
I didn't look into your second question because - in essence - it is another question.
you can do that in one statement like:
Range("G6", Range("G6").End(xlDown)).Find("7000").Resize(XCount - YCount).EntireRow.Insert
as for your second question you can use something like follows (explanations in comments, so you can adjust it to your needs):
With PLJob 'reference PLJob
With .Range("B2", .Cells(.Rows.Count, 1).End(xlUp)) 'reference its columns A and B cells from row 2 down to column A last not empty one
.Formula = .Resize(1).Formula 'copy/paste formulas
End With
End With
Related
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
In a previous post user: LocEngineer managed to help me to write a finding function that would find the least frequent values in a column of a particular category.
The VBA code works well for the most part with some particular issues, and the previous question had been answered with a sufficiently good answer already, so I thought this required a new post.
LocEngineer: "Holy smoking moly, Batman! If THAT truly is your sheet.... I'd say: forget "UsedRange". That won't work well enough with THAT spread... I've edited the above code using more hardcoded values. Please adapt the values according to your needs and try that. Woah what a mess."
Here is the code:
Sub frequenz()
Dim col As Range, cel As Range
Dim letter As String
Dim lookFor As String
Dim frequency As Long, totalRows As Long
Dim relFrequency As Double
Dim RAN As Range
RAN = ActiveSheet.Range("A6:FS126")
totalRows = 120
For Each col In RAN.Columns
'***get column letter***
letter = Split(ActiveSheet.Cells(1, col.Column).Address, "$")(1)
'*******
For Each cel In col.Cells
lookFor = cel.Text
frequency = Application.WorksheetFunction.CountIf(Range(letter & "2:" & letter & totalRows), lookFor)
relFrequency = frequency / totalRows
If relFrequency <= 0.001 Then
cel.Interior.Color = ColorConstants.vbYellow
End If
Next cel
Next col
End Sub
The Code is formatted like this: (Notice the merged cells that head each column for titles. The titles go down to row 5 and data starts on row 5) (Also Notice that the rows are very much filled with empty columns, sometimes more so than data.)
Finally, one important change I cant figure out is how to get it to ignore blank cells.
Please advise. Thank you.
If the 2 adjustments to be made are to 1. exclude headers, and 2. blank cells
Exclude the headers in way a bit more dynamic; this excludes the top 6 rows:
With ActiveSheet.UsedRange
Set ran = .Offset(6, 0).Resize(.Rows.Count - 6, .Columns.Count)
End With
In the inner For loop, after this line For Each cel In col.Cells you need an IF:
For Each cel In col.Cells
If Len(cel.Value2) > 0 Then...
Here is the modified version (untested):
Option Explicit
Sub frequenz()
Const MIN_ROW As Long = 6
Const MAX_ROW As Long = 120
Dim col As Range
Dim cel As Range
Dim rng As Range
Dim letter As String
Dim lookFor As String
Dim frequency As Long
With ActiveSheet.UsedRange
Set rng = .Offset(MIN_ROW, 0).Resize(MAX_ROW, GetMaxCell.Column)
End With
For Each col In rng.Columns
letter = Split(ActiveSheet.Cells(1, col.Column).Address, "$")(1)
For Each cel In col
lookFor = cel.Value2
If Len(lookFor) > 0 Then 'process non empty values
frequency = WorksheetFunction.CountIf( _
Range(letter & "2:" & letter & MAX_ROW), lookFor)
If frequency / MAX_ROW <= 0.001 Then
cel.Interior.Color = ColorConstants.vbYellow
End If
End If
Next cel
Next col
End Sub
.
Updated to use a new function when determining the last row and column containing values:
Public Function GetMaxCell(Optional ByRef rng As Range = Nothing) As Range
'It returns the last cell of range with data, or A1 if Worksheet is empty
Const NONEMPTY As String = "*"
Dim lRow As Range, lCol As Range
If rng Is Nothing Then Set rng = Application.ActiveWorkbook.ActiveSheet.UsedRange
If WorksheetFunction.CountA(rng) = 0 Then
Set GetMaxCell = rng.Parent.Cells(1, 1)
Else
With rng
Set lRow = .Cells.Find(What:=NONEMPTY, LookIn:=xlFormulas, _
After:=.Cells(1, 1), _
SearchDirection:=xlPrevious, _
SearchOrder:=xlByRows)
Set lCol = .Cells.Find(What:=NONEMPTY, LookIn:=xlFormulas, _
After:=.Cells(1, 1), _
SearchDirection:=xlPrevious, _
SearchOrder:=xlByColumns)
Set GetMaxCell = .Parent.Cells(lRow.Row, lCol.Column)
End With
End If
End Function
I am trying to loop through a column and if cells = "what i'm lookng for" then do something.
I have this so far, where I'm off is in the if statement where I check for the "name":
Option Explicit
Sub test()
Dim wksDest As Worksheet
Dim wksSource As Worksheet
Dim rngSource As Range
Dim name As String
Dim LastRow As Long
Dim LastCol As Long
Dim c As Long
Application.ScreenUpdating = False
Set wksSource = Worksheets("Sheet1")
With wksSource
LastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
For c = 16 To 20
LastRow = .Cells(.Rows.Count, c).End(xlUp).Row
Set rngSource = .Range(.Cells(5, 16), .Cells(LastRow, 16))
name = rngSource.Value
If name = "mark"
do something
End If
Next c
End With
Application.ScreenUpdating = True
'MsgBox "Done!", vbExclamation
End Sub
OK Chris
Maybe a bit of simplification is required but also a few assumptions.
It doesn't seem like LastCol is being used for anything - so let's assume this is the Column you want to loop through.
Your loop has fixed start and end values yet you are determining the LastRow - so let's assume you want to start from row 5 (in your code) and loop to the LastRow in the LastCol.
In order to determine LastCol you must have data in the row you are using to do this - so let's assume that there are values in row 1 in all columns up to column you want to loop say 16 (in your code).
If you want to (IF) test for a single (string) value in this case then you must arrange for your rngSource to be a single cell value. You also don't need to assign this to a variable unless you need to use it again.
Finally, if you want to check for other values you may want to consider using a SELECT CASE structure in place of your IF THEN structure.
Have a look at the following and change my assumptions to meet your requirement - good luck.
Sub test()
Dim wksDest As Worksheet
Dim wksSource As Worksheet
Dim rngSource As Range
Dim name As String
Dim LastRow As Long
Dim LastCol As Long
Dim c As Long
Application.ScreenUpdating = False
Set wksSource = Worksheets("Sheet1")
With wksSource
LastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
LastRow = .Cells(Rows.Count, LastCol).End(xlUp).Row
FirstRow = 5
For c = FirstRow To LastRow
If .Range(.Cells(c, LastCol), .Cells(c, LastCol)).Value = "Mark" Then
MsgBox ("do something")
End If
Next c
End With
End Sub
You can just do that with one line.
If Not IsError(Application.Match(ValueToSearchFor, RangeToSearchIn, 0)) Then
'The value found in the given range
End If
Example:
Search for "Canada" in column C of sheet named "Country"
If Not IsError(Application.Match("Canada", Sheets("Country").Range("C:C"), 0)) Then
'The value found in the given range
End If
Pass value to find and Column where value need to be checked. It will return row num if its found else return 0.
Function checkForValue(FindString As String,ColumnToCheck as String) As Long
SheetLastRow = Sheets("Sheet1").Cells.Find(What:="*", SearchOrder:=xlRows, SearchDirection:=xlPrevious, LookIn:=xlValues).row
With Sheets("Sheet1").Range("$" & ColumnToCheck & "$1:$" & ColumnToCheck & "$" & CStr(SheetLastRow) )
Set rng = .Find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
lookat:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not rng Is Nothing Then
checkForValue = rng.row 'return row its found
'write code you want.
Else
checkForValue = 0
End If
End With
End Function
I tried Hari's suggestion, but Application.Match works weird on range names (not recognizing them...)
Changed to: WorksheetFunction.Match(...
It works, but when value is not present A runtime ERROR jumps before IsError(...) is evaluated.
So I had to write a simple -no looping- solution:
dim Index as Long
Index = -1
On Error Resume Next
Index = WorksheetFunction.Match(Target,Range("Edificios"), 0) 'look for Target value in range named: Edificios
On Error GoTo 0
If Index > 0 Then
' code for existing value found in Range # Index row
End If
Remeber Excel functions first index = 1 (no zero based)
Hope this helps.
I'm guessing what you really want to do is loop through your range rngSource. So try
Set rngSource = .Range(.Cells(5, 16), .Cells(LastRow, 16))
for myCell in rngSource
if myCell.Value = "mark" then
do something
end if
next myCell
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
Sheet1 Sheet2
Above i have two images link that i have captured from my excel document (Sheet1, Sheet 2)
Here's a brief description basically, I just want my macros to compare Part Number (column C) from both sheets and find out the differences. And when a string differences is detected between both sheets it will highlight the row on both sheet of BOM-list to indicate to the user the differences in the Part-number(column C). But that is a problem too as seen in the images there is some rows with "space" which the loop have to take care of to prevent comparing an empty string thus giving wrong result.
Sorry for my poor command of English and explanation if its not clear to you. Can someone guide me on this i'm rather aimless on where or how to start and i have to complete this within a week without prior knowledge on excel-VBA programming understanding.
Updated:
I have updated my post can someone take a look and give me your opinion on how i can change the code to highlight the whole row of column A to P instead of column C Range value differences only?
Sub differences()
Dim ws1 As Worksheet, ws2 As Worksheet
Dim lastRow1 As Integer, lastrow2 As Integer
Dim rng1 As Range, rng2 As Range, temp As Range, found As Range
Application.ScreenUpdating = False
Set ws1 = ThisWorkbook.Sheets("Sheet1")
Set ws2 = ThisWorkbook.Sheets("Sheet2")
lastRow1 = ws1.Range("A" & Rows.Count).End(xlUp).Row
lastrow2 = ws2.Range("A" & Rows.Count).End(xlUp).Row
Set rng1 = ws1.Range("C21:C" & lastRow1)
Set rng2 = ws2.Range("C21:C" & lastrow2)
For Each temp In rng1
Set found = Find_Range(temp.Value, rng2, , xlWhole)
If found Is Nothing Then
temp.Interior.ColorIndex = 3
End If
Next temp
For Each temp In rng2
Set found = Find_Range(temp.Value, rng1, , xlWhole)
If found Is Nothing Then
temp.Interior.ColorIndex = 3
End If
Next temp
End Sub
Function Find_Range(Find_Item As Variant, Search_Range As Range, Optional LookIn As Variant, Optional LookAt As Variant, Optional MatchCase As Boolean) As Range
Dim c As Range
Dim firstAddress As String
If IsMissing(LookIn) Then LookIn = xlValues 'xlFormulas
If IsMissing(LookAt) Then LookAt = xlPart 'xlWhole
If IsMissing(MatchCase) Then MatchCase = False
With Search_Range
Set c = .Find(What:=Find_Item, LookIn:=LookIn, LookAt:=LookAt, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=MatchCase, SearchFormat:=False)
If Not c Is Nothing Then
Set Find_Range = c
firstAddress = c.Address
Do
Set Find_Range = Union(Find_Range, c)
Set c = .FindNext(c)
Loop While Not c Is Nothing And c.Address <> firstAddress
End If
End With
End Function
As I cant see the the images, I will make the assumption that what you are trying to do is check if a part number exists in the other list and if not then highlight it.
Off the top of my head this is what you will basically need to do.
Public Sub Test()
CompareRange Sheet1.Range("A2", "A8"), Sheet2.Range("A2", "A8")
End Sub
Public Sub CompareRange(range1 As Range, range2 As Range)
Dim CompareCell As Range
Dim CheckCell As Range
Dim CellFound As Boolean
For Each CompareCell In range1.Cells
CellFound = False
For Each CheckCell In range2.Cells
If CheckCell.Text = CompareCell.Text Then
CellFound = True
End If
Next CheckCell
If Not CellFound Then
CompareCell.Interior.Color = vbYellow
End If
Next CompareCell
End Sub
One thing to note is that this function assumes that you have a single column range. otherwise it will check all the cells in your ranges and probably highlight more than you intended.
EDIT
As far as Highlighting the Row
try adding this to your find loop
Dim CompareSheet as Worksheet 'Add at top of function
'Add to the For Each Loop
Set CompareSheet = temp.Worksheet
CompareSheet.Range("A" & temp.Row, "P" & temp.Row).Interior.ColorIndex = 3