I am trying to does the following:
Compare the value (a string of characters) that is stored in column B of worksheet "State = Closed", to all the values in column A of another worksheet called "Match List".
Delete any row in the "State = Closed" that does not have a match to the corresponding "Match List" value.
The code needs to work with any length (as the number of rows will change) list in "Match List", as well as any length "State = Closed" worksheet.
Sub ListRemove()
Application.ScreenUpdating = False
Dim i As Integer
Dim b As Integer
Dim Lastrow As Long
Dim Lastrowb As Long
Dim Del As Variant
Worksheets("Match List").Activate
Set Del = Range("A1:A67") '<--- This needs to be modified to work with any length Match List
Lastrowb = Worksheets("State = Closed").Cells(Rows.Count, "A").End(xlUp).Row
Lastrow = Cells(Rows.Count, "A").End(xlUp).Row
For i = 1 To Lastrow
For b = 1 To Lastrowb
If Worksheets("State = Closed").Cells(i, 2).Value <> Del(b) Then
Worksheets("State = Closed").Rows(i).EntireRow.Delete
End If
Next
Next
Application.ScreenUpdating = True
Worksheets("State = Closed").Activate
End Sub
This deletes every row in the "State = Closed" worksheet instead of just the rows that do not contain a corresponding value in the Match List worksheet.
Find my code below. Two for-loops to check for each value if there is an identical entry in any cell of the second sheet.
Sub List_Remove()
Dim i As Integer
Dim j As Integer
Dim k As Boolean
Dim shA As Worksheet
Dim shB As Worksheet
Set shA = Sheets("Sheet1") 'Worksheet that you want to compare with
Set shB = Sheets("Sheet2") 'Worksheet you want to delete rows from
For i = shB.UsedRange.Rows.Count To 1 Step -1
k = False
For j = 1 To shA.UsedRange.Rows.Count
If shB.Cells(i, 1).Value = shA.Cells(j, 1).Value Then
k = True
End If
Next
If k = False Then
shB.Rows(i).Delete
End If
Next
EndSub
This code is tested. Note use of working directly with objects.
Option Explicit
Sub ListRemove()
Application.ScreenUpdating = False
Dim matchList As Worksheet
Set matchList = Worksheets("Match List")
Dim matchRange As Range
Set matchRange = matchList.Range("A1:A" & matchList.Cells(matchList.Rows.Count, 1).End(xlUp).Row)
Dim closedList As Worksheet
Set closedList = Worksheets("State = Closed")
Dim searchRows As Long
searchRows = closedList.Cells(closedList.Rows.Count, 1).End(xlUp).Row
Dim i As Long
For i = searchRows To 1 Step -1
If IsError(Application.Match(closedList.Cells(i, 1).Value, matchRange, 0)) Then
closedList.Cells(i, 1).EntireRow.Delete
End If
Next
End Sub
Delete Rows (Union)
The Code
Option Explicit
Sub ListRemove()
Application.ScreenUpdating = False
' Constants
Const mlName As String = "Match List"
Const mlFR As Long = 1
Const mlCol As Variant = "A" ' e.g. 1 or "A"
Const scName As String = "State = Closed"
Const scFR As Long = 1
Const scCol As Variant = "B" ' e.g. 1 or "A"
' Workbook
Dim wb As Workbook: Set wb = ThisWorkbook
' Match List
Dim ml As Worksheet: Set ml = wb.Worksheets(mlName)
Dim mlLR As Long: mlLR = ml.Cells(ml.Rows.Count, mlCol).End(xlUp).Row
Dim Del As Variant
Del = ml.Range(ml.Cells(mlFR, mlCol), ml.Cells(mlLR, mlCol)).Value
' State = Closed
Dim sc As Worksheet: Set sc = wb.Worksheets(scName)
Dim scLR As Long: scLR = sc.Cells(sc.Rows.Count, scCol).End(xlUp).Row
Dim rng As Range
Set rng = sc.Range(sc.Cells(scFR, scCol), sc.Cells(scLR, scCol))
' Collecting Cells
Dim cel As Range, URng As Range
For Each cel In rng.Cells
If IsError(Application.Match(cel.Value, Del, 0)) Then
GoSub collectCells
End If
Next
' Deleting Rows
'If Not URng Is Nothing Then URng.EntireRow.Delete
' First test with Hiding Rows.
If Not URng Is Nothing Then URng.EntireRow.Hidden = True
Application.ScreenUpdating = True
sc.Activate
Exit Sub
collectCells:
If Not URng Is Nothing Then
Set URng = Union(URng, cel)
Else
Set URng = cel
End If
Return
End Sub
Related
I'm trying to compare column A in sheet2 to column A in sheet1 and when there's a match, copy the row from sheet1 to sheet3 with the same order. And if there is a repetition, it should be included too. I also need it to show the mismatching values empty. I did this macro but I can not allow the duplicates to be included.
Sub compareAndCopy()
Dim lastRowE As Long
Dim lastRowF As Long
Dim lastRowM As Long
Dim foundTrue As Boolean
' stop screen from updating to speed things up
Application.ScreenUpdating = False
lastRowE = Sheets("Sheet2").Cells(Sheets("Sheet2").Rows.Count, "A").End(xlUp).Row
lastRowF = Sheets("Sheet1").Cells(Sheets("Sheet1").Rows.Count, "A").End(xlUp).Row
lastRowM = Sheets("Sheet3").Cells(Sheets("Sheet3").Rows.Count, "B").End(xlUp).Row
For i = 1 To lastRowE
foundTrue = False
For j = 1 To lastRowF
If Sheets("Sheet2").Cells(i, 1).Value = Sheets("Sheet1").Cells(j, 1).Value Then
lastRowM = lastRowM + 1
Sheets("Sheet1").Rows(i).Copy Destination:= _
Sheets("Sheet3").Rows(lastRowM)
foundTrue = True
Exit For
End If
Next j
'If Not foundTrue Then
' MsgBox ("didn't find string: " & Sheets("Sheet2").Cells(i, 2).value)
'End If
Next i
' allow screen updating
Application.ScreenUpdating = True
End Sub
Group Data
Loops through probably unique values in column A of Sheet2.
For each cell value, it uses the Find and FindNext methods to find all the matching cells in column A of Sheet1.
Then it writes each of the cell values to a key, and using Union, combines each matching cell to a range object in the corresponding item.
Then it loops through the dictionary and copies the entire rows of each item (range) to Sheet3.
Finally, it clears the newly added values in column A of Sheet3.
The result in Sheet3 is data from Sheet1 grouped by the values in column A of Sheet2.
Option Explicit
Sub CompareAndCopy()
Const eName As String = "Sheet2"
Const eCol As String = "A"
Const efRow As Long = 1 ' don't you have headers?
Const fName As String = "Sheet1"
Const fCol As String = "A"
Const ffRow As Long = 1 ' don't you have headers?
Const mName As String = "Sheet3"
Const mCol As String = "B" ' "A" is empty!
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ews As Worksheet: Set ews = wb.Worksheets(eName)
Dim elRow As Long: elRow = ews.Cells(ews.Rows.Count, eCol).End(xlUp).Row
If elRow < efRow Then Exit Sub ' no data
Dim erg As Range: Set erg = ews.Cells(efRow, eCol).Resize(elRow - efRow + 1)
'Debug.Print erg.Address
Dim fws As Worksheet: Set fws = wb.Worksheets(fName)
Dim flRow As Long: flRow = fws.Cells(fws.Rows.Count, fCol).End(xlUp).Row
If flRow < ffRow Then Exit Sub ' no data
Dim frg As Range:
Set frg = fws.Cells(ffRow, fCol).Resize(flRow - ffRow + 1)
'Debug.Print frg.Address
Dim mws As Worksheet: Set mws = wb.Worksheets(mName)
Dim mifCell As Range
Set mifCell = mws.Cells(mws.Rows.Count, mCol).End(xlUp).Offset(1) _
.EntireRow.Columns("A") ' entire rows
Dim mfCell As Range: Set mfCell = mifCell
'Debug.Print mfCell.Address
Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
dict.CompareMode = vbTextCompare
Application.ScreenUpdating = False
Dim frCount As Long: frCount = frg.Rows.Count
Dim eCell As Range
Dim eValue As Variant
Dim fCell As Range
Dim FirstAddress As String
For Each eCell In erg.Cells
eValue = eCell.Value
Set fCell = frg.Find(eValue, frg.Cells(frCount), xlFormulas, xlWhole)
If Not fCell Is Nothing Then
FirstAddress = fCell.Address
Do
If dict.Exists(eValue) Then
Set dict(eValue) = Union(dict(eValue), fCell)
Else
Set dict(eValue) = fCell
End If
Set fCell = frg.FindNext(fCell)
Loop Until fCell.Address = FirstAddress
End If
Next eCell
If dict.Count = 0 Then Exit Sub ' no data¸
Dim rg As Range
Dim Item As Variant
Dim irCount As Long
For Each Item In dict.Items
irCount = Item.Cells.Count
'Debug.Print Item.Address, irCount
Item.EntireRow.Copy mfCell.EntireRow
Set mfCell = mfCell.Offset(irCount)
Next Item
mifCell.Resize(mfCell.Row - mifCell.Row).ClearContents ' or .Clear
Application.ScreenUpdating = True
MsgBox "Data grouped.", vbInformation
End Sub
I'm trying to return the partial match string on a column right beside the column with the text I'm trying to search within. This is the code I tried to write. What would be a better way to do this?
Essentially I have a column with:
Column 1
aaaaa1111
...
zzzzz9999
Column 2
aaa
bbb
..
zzz
I want to return column 2 values to the column adjacent to column 1 where the column 2's string can be found within column 1.
Sub match()
Dim ws As Worksheet
Dim vendors As Range
Dim description As Range
Dim match As Range
Dim cell As Range
Dim j As Integer
Dim i As Integer
Set vendors = ws.Range("ae2:ae1007").Text
Set description = ws.Range("o2:o32609")
Set match = ws.Range("p2:p32609")
For i = 2 To 32609
For j = 2 To 1007
If InStr(description.Cells(i, "O"), vendors.Range(j, "AE")) > 0 Then
match.Cells(i, "P") = vendors.Range(j, "AE").Text
Else: match.Cells(i, "P") = "#N/A"
End If
Next j
Next i
End Sub
Update: (I get run-time error '91' on line 9)
Sub match()
Dim ws As Worksheet
Dim cell As Range
Dim j As Integer
Dim i As Integer
For i = 2 To 32609
For j = 2 To 1007
If InStr(ws.Cells(i, "O"), ws.Cells(j, "AE")) > 0 Then
ws.Cells(i, "P") = ws.Cells(j, "AE").Text
Else: ws.Cells(i, "P") = "#N/A"
End If
Next j
Next i
End Sub
You are getting error 91 because you declared ws but did not set ws to any worksheet.
The code below should run pretty fast since it process the data in an array (read/write from cells is a very slow process).
Option Explicit
Sub FindMatch()
Const vendorCol As String = "AE"
Const descCol As String = "O"
Const matchCol As String = "P"
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1") 'Change name accordingly
'==== Get a list of unique vendor names
Dim vendorDict As Object
Set vendorDict = CreateObject("Scripting.Dictionary")
vendorDict.CompareMode = vbTextCompare
Dim vendorLastRow As Long
Dim vendorInput As Variant
'Assign the values of the vendor names to array
vendorLastRow = ws.Cells(ws.Rows.Count, vendorCol).End(xlUp).Row
vendorInput = ws.Range(ws.Cells(2, vendorCol), ws.Cells(vendorLastRow, vendorCol)).Value
'Loop through the array and add to dictionary if it's not already in it
Dim n As Long
For n = 1 To UBound(vendorInput, 1)
If Not vendorDict.Exists(vendorInput(n, 1)) Then vendorDict.Add vendorInput(n, 1), 1
Next n
Dim vendorArr As Variant
vendorArr = vendorDict.keys
Set vendorDict = Nothing
Erase vendorInput
'====
'Assign the values of description to array
Dim descLastRow As Long
Dim descArr As Variant
descLastRow = ws.Cells(ws.Rows.Count, descCol).End(xlUp).Row
descArr = ws.Range(ws.Cells(2, descCol), ws.Cells(descLastRow, descCol)).Value
'Create an array of the same size as the description for match result, will be used to write in to the worksheet once at the end
Dim matchArr() As Variant
ReDim matchArr(1 To UBound(descArr, 1), 1 To 1) As Variant
'Loop through the description array and within the loop, check if there's a match in the vendor array
Dim i As Long
For i = 1 To UBound(descArr, 1)
For n = 0 To UBound(vendorArr)
If InStr(1, descArr(i, 1), vendorArr(n), vbTextCompare) <> 0 Then
'If match found, assign the vendor name to the match array
matchArr(i, 1) = vendorArr(n)
Exit For
End If
Next n
'If no match, return NA error
If matchArr(i, 1) = vbNullString Then matchArr(i, 1) = CVErr(xlErrNA)
Next i
ws.Cells(2, matchCol).Resize(UBound(matchArr, 1)).Value = matchArr
Erase descArr
Erase matchArr
End Sub
Compare Two Columns
This is a basic example that loops through column O and compares each value against each value in column AE. Match is no good because the values in AE need to be contained in O. You can always improve efficiency by using arrays as illustrated in Raymond Wu's answer.
On the other hand, you could loop through column AE and use the Find and FindNext methods to find all matches in column O which might also be more efficient.
Option Explicit
Sub MatchVendors()
' s - Source (read from ('vendors'))
' d - Destination (read from ('description') and written to ('match'))
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim sws As Worksheet: Set sws = wb.Worksheets("Sheet1") ' adjust, often...
Dim dws As Worksheet: Set dws = wb.Worksheets("Sheet1") ' ... different
Dim slRow As Long: slRow = sws.Range("AE" & sws.Rows.Count).End(xlUp).Row
If slRow < 2 Then Exit Sub ' no data in source
Dim srg As Range: Set srg = sws.Range("AE2:AE" & slRow)
Dim dlRow As Long: dlRow = dws.Range("O" & dws.Rows.Count).End(xlUp).Row
If dlRow < 2 Then Exit Sub ' no data in destination
Dim drg As Range: Set drg = dws.Range("O2:O" & dlRow)
Application.ScreenUpdating = False
Dim sCell As Range
Dim dCell As Range
Dim IsMatch As Boolean
For Each dCell In drg.Cells
' Read (Search)
For Each sCell In srg.Cells
' Either 'contains'...
If InStr(1, dCell.Value, sCell.Value, vbTextCompare) > 0 Then
' ... or 'begins with':
'If InStr(1, dCell.Value, sCell.Value, vbTextCompare) = 1 Then
IsMatch = True
Exit For
End If
Next sCell
' Write
If IsMatch Then
dCell.EntireRow.Columns("P").Value = sCell.Value
IsMatch = False
Else
dCell.EntireRow.Columns("P").Value = "#N/A"
End If
Next dCell
Application.ScreenUpdating = True
MsgBox "Vendors matched to Descriptions.", vbInformation
End Sub
Sheet1 is a continuous list of everything being recorded and kept.
Sheet2 is an updated list that is retrieved, with updated lines and new lines. Within the lists in column A is a unique ID for every entry in numeric value.
I am trying to go through every unique ID in sheet2, look for a match in sheet1
if there is a match, replace that entire row values with the new values from sheet2
if there is no match it needs to be placed in the last blank row (+1 from xlUp).
I have tried other ways that are not below like using scripting.dictionary.
The way I am trying to do this results in every cell that the “for” is looking at to be true for the if not equal. Every item is posted multiple times below xlUp.
Sub test()
Dim enter As Worksheet
Dim take As Worksheet
Set enter = Worksheets("Sheet1")
Set take = Worksheets("Sheet2")
Dim a1 As Long
Dim b1 As Long
Dim c1 As Long
a1 = take.Cells(Rows.Count, 1).End(xlUp).Row
b1 = enter.Cells(Rows.Count, 1).End(xlUp).Row
c1 = enter.Cells(Rows.Count, 1).End(xlUp).Row + 1
For i = 1 To a1 'this statement works fine to find the matching value to replace.
For K = 1 To b1
If take.Cells(i, 1) = enter.Rows(K, 1) Then
enter.Rows(i).EntireRow = take.Rows(K).EntireRow.Value
End If
Next
Next
'below is other things i have tried
'For I = 1 To a1
' For J = 1 To b1
' If enter.Cells(J, 1) <> take.Cells(I, 1) Then
' enter.Rows(c1).EntireRow = take.Rows(I).EntireRow.Value
' c1 = c1 + 1
' End If
' Next
'Next
'For i = 1 To a1
' For j = 1 To b1
' If take.Cells(i, 1) = enter.Cells(j, 1) Then
' enter.Rows(j).EntireRow = take.Rows(i).EntireRow.Value
' GoTo Skip
' ElseIf j = b1 Then
' enter.Rows(c1).EntireRow = take.Rows(i).EntireRow.Value
' c1 = c1 + 1
' End If
' Next
'Skip:
'Next
End Sub
hy
Public Sub MyCopy()
Dim wsSource As Worksheet, wsTarget As Worksheet
Set wsSource = ThisWorkbook.Worksheets("ws1")
Set wsTarget = ThisWorkbook.Worksheets("ws2")
Dim col As String
col = "A"
Dim i As Long, targetRow As Long, q As Long
Dim sourceRange As Range
With wsSource
For i = 1 To .Cells(.Rows.Count, col).End(xlUp).Row
Set sourceRange = .Range(col & i)
targetRow = GetDataRow(wsTarget, col, sourceRange.value)
For q = 0 To 30
wsTarget.Range(col & targetRow).Offset(0, q).value = sourceRange.Offset(0, q).value
Next q
Next i
End With
End Sub
Private Function GetDataRow(ws As Worksheet, col As String, value As String) As Long
With ws
Dim lastRow As Long, i As Long
lastRow = .Cells(.Rows.Count, col).End(xlUp).Row
For i = 1 To lastRow
If .Range(col & i).value = value Then
GetDataRow = i
GoTo exitFunc
End If
Next i
GetDataRow = lastRow + 1
End With
exitFunc:
End Function
Update Worksheet (For Each ... Next, Application.Match)
Option Explicit
Sub UpdateWorksheet()
Const sName As String = "Sheet2"
Const sFirst As String = "A1"
Const dName As String = "Sheet1"
Const dFirst As String = "A1"
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim slCell As Range
Set slCell = sws.Cells(sws.Rows.Count, sws.Range(sFirst).Column).End(xlUp)
Dim srg As Range: Set srg = sws.Range(sFirst, slCell)
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
Dim dlCell As Range:
Set dlCell = dws.Cells(dws.Rows.Count, dws.Range(dFirst).Column).End(xlUp)
Dim drg As Range: Set drg = dws.Range(dFirst, dlCell)
Application.ScreenUpdating = False
Dim sCell As Range
Dim cIndex As Variant
For Each sCell In srg.Cells
cIndex = Application.Match(sCell.Value, drg, 0)
If IsNumeric(cIndex) Then
drg.Cells(cIndex).EntireRow.Value = sCell.EntireRow.Value
Else
Set dlCell = dlCell.Offset(1)
dlCell.EntireRow.Value = sCell.EntireRow.Value
End If
Next sCell
Application.ScreenUpdating = True
End Sub
Not very experienced with Excel coding, but I got a decent way myself. But I cant figure this thing out.
Looking to automate a sheet so that when a cell in column E is set to "Staffed", the macro will move the entire row from the table in Sheet A to the Table in Sheet B. At the moment, the macro is placing the cut and pasted row below the table, sometimes 20 something rows below, on the new sheet.
I would appreciate the help. Thank you
Sub NtS()
Dim xRg As Range
Dim xCell As Range
Dim I As Long
Dim J As Long
Dim K As Long
I = Worksheets("Clients Needing Staffed").UsedRange.Rows.Count
J = Worksheets("Clients Staffed").UsedRange.Rows.Count
If J = 1 Then
If Application.WorksheetFunction.CountA(Worksheets("Clients Staffed").UsedRange) = 0 Then J = 0
End If
Set xRg = Worksheets("Clients Needing Staffed").Range("E1:E" & I)
On Error Resume Next
Application.ScreenUpdating = False
For K = 1 To xRg.Count
If CStr(xRg(K).Value) = "Staffed" Then
xRg(K).EntireRow.Copy Destination:=Worksheets("Clients Staffed").Range("A" & J + 1)
xRg(K).EntireRow.Delete
If CStr(xRg(K).Value) = "Staffed" Then
K = K - 1
End If
J = J + 1
End If
Next
Application.ScreenUpdating = True
End Sub
Copy and Delete Rows (Union)
Option Explicit
Sub NtS()
' Constants
' Source
Const srcName As String = "Clients Needing Staffed"
Const srcFirstRow As Long = 2
Const srcLastRowCol As Variant = "E" ' e.g. 1 or "A", 5 or "E"...
Const srcCritCol As Variant = "E" ' e.g. 1 or "A", 5 or "E"...
Const srcCriteria As String = "Staffed"
' Target
Const tgtName As String = "Clients Staffed"
' The following parameter has to be 1 or "A", because copying entire row.
Const tgtFirstCol As Variant = "A" ' e.g. 1 or "A"
Const tgtFirstRowCol As Variant = "A" ' e.g. 1 or "A"
' Other
Dim wb As Workbook: Set wb = ThisWorkbook ' The workbook with this code.
' Source
Dim src As Worksheet: Set src = wb.Worksheets(srcName)
Dim srcLastRow As Long
srcLastRow = src.Cells(src.Rows.Count, srcLastRowCol).End(xlUp).Row
If srcLastRow < srcFirstRow Then Exit Sub
' Define Criteria column range.
Dim rng As Range: Set rng = src.Range(src.Cells(srcFirstRow, srcCritCol), _
src.Cells(srcLastRow, srcCritCol))
Application.ScreenUpdating = False
' Loop through each cell of Criteria column range to search
' for Criteria value.
Dim cel As Range, uRng As Range, i As Long, k As Long
For Each cel In rng.Cells
If cel.Value = srcCriteria Then
k = k + 1
If Not uRng Is Nothing Then
Set uRng = Union(uRng, cel.EntireRow)
Else
Set uRng = cel.EntireRow
End If
End If
Next cel
If uRng Is Nothing Then
MsgBox "Data has already been deleted.", vbExclamation, "Done Nothing"
Exit Sub
End If
' Target
' Define Target First Row.
Dim tgt As Worksheet: Set tgt = wb.Worksheets(tgtName)
Dim tgtFirstRow As Long
tgtFirstRow = tgt.Cells(tgt.Rows.Count, tgtFirstRowCol).End(xlUp).Row + 1
' Copy 'collected' range of rows to Target worksheet starting
' from Target First Cell.
uRng.Copy tgt.Cells(tgtFirstRow, tgtFirstCol)
' Delete 'collected' range of rows.
uRng.EntireRow.Delete
' Finish
Application.ScreenUpdating = True
' Inform user.
MsgBox "Data copied and deleted.", vbInformation, "Success"
End Sub
My code currently searches through Sheet1 and copies rows into Sheet2 if it matches the array of strings in strSearch. How can I make it so that it outputs "No Search Found" as a row on Sheet2 if there are no rows that contain the strSearch?
Dim ws1 As Worksheet, ws2 As Worksheet
Dim firstRowWs1 As Long
Dim lastRowWs1 As Long
Dim lastRowWs2 As Long
Dim searchColumnWs1 As Integer
Dim i As Integer
Dim check As Variant
Dim strSearch As Variant
Set ws1 = Worksheets("Sheet1")
Set ws2 = Worksheets("Sheet2")
With ws2
lastRowWs1 = ws1.UsedRange.Rows.Count
lastRowWs2 = ws2.UsedRange.Rows.Count
firstRowWs1 = 1
searchColumnWs1 = 10
strSearch = Array("John", "Jim")
For i = firstRowWs1 To lastRowWs1
For Each check In strSearch
If check = ws1.Cells(i, searchColumnWs1).Value Then
ws1.Rows(i).Copy (ws2.Rows(lastRowWs2 + 1))
ws2.Rows(lastRowWs2 + 1).Columns("A:B").Insert xlToRight
lastRowWs2 = lastRowWs2 + 1
ws1.Rows(i).Delete shift:=xlUp
i = i - 1
Exit For
End If
Next check
Next i
End With
Keep track of whether or not you found matches, and add the text after your loop.
Eg:
Dim foundMatches as Boolean
foundMatches = False
For i = firstRowWs1 To lastRowWs1
For Each check In strSearch
If check = ws1.Cells(i, searchColumnWs1).Value Then
foundMatches = True
... etc
End If
Next check
Next i
If Not foundMatches then
' print "no rows found" somewhere
end if