Best way to use "Find" when having many words to test

Brutusar

Board Regular
Joined
Nov 23, 2019
Messages
166
Office Version
  1. 365
Platform
  1. Windows
Hi, I need to loop thru a range in Active sheet, (Column E from first to last row) and find one of many different possible words. If a word is found, the hole row will be copied to Sheet2.
So far no problems.

However, I need to check each row for more than 100 different words, and the list of words is dynamic. Words will be deleted, and other added. One way to do this is to read the words into an array every time the code is running, and then loop thru that array for each row.

It will rarely be more than 500 rows, but with 100-150 words to check for it will take a little time. So far I have just been searching for 15-20 words, all static, but the needs have changed.

Does anyone has any suggestion to the best way of doing this?

I have up to now used the code below, but it has become impractical now.

VBA Code:
Sub Find_and_copy ()
 Dim sh1 As Worksheet, sh2 As Worksheet, rng As Range, cel As Range
 Dim rngCopy As Range, lastR1 As Long, lastR2 As Long
 Dim strSearch1 As String, strSearch2 As String
 
 strSearch1 = "teststring1"
 strSearch2 = "teststring2"
 Set sh1 = ActiveSheet         
 Set sh2 = Worksheets("Sheet2")
 lastR1 = sh1.Range("C" & Rows.count).End(xlUp).Row
 lastR2 = sh2.Range("A" & Rows.count).End(xlUp).Row + 1
 
 Set rng = sh1.Range("C2:C" & lastR1)
 For Each cel In rng.cells
    If cel.Value = strSearch Or cel.Value = strSearch2 Then
        If rngCopy Is Nothing Then
            Set rngCopy = sh1.Rows(cel.Row)
        Else
            Set rngCopy = Union(rngCopy, sh1.Rows(cel.Row))
        End If
    End If
 Next
 If Not rngCopy Is Nothing Then
    rngCopy.Copy Destination:=sh2.cells(lastR2, 1)
 End If
End Sub
 

Excel Facts

Create a chart in one keystroke
Select the data and press Alt+F1 to insert a default chart. You can change the default chart to any chart type
Try this:
However, I need to check each row for more than 100 different words, and the list of words is dynamic.
Put the list say in sheet3 col A


Rich (BB code):
Sub Find_and_copy1()
 Dim sh1 As Worksheet, sh2 As Worksheet, rng As Range, cel As Range
 Dim rngCopy As Range, lastR1 As Long, lastR2 As Long
 Dim strSearch1 As String, strSearch2 As String
 Dim va, vb
 Dim i As Long
 Dim d As Object
 

 Set sh1 = ActiveSheet
 Set sh2 = Worksheets("Sheet2")
 
 lastR1 = sh1.Range("C" & Rows.Count).End(xlUp).Row
 lastR2 = sh2.Range("A" & Rows.Count).End(xlUp).Row + 1
 
 With Sheets("Sheet3")  'put the list here, amend as needed
    va = .Range("A1", .Cells(.Rows.Count, "A").End(xlUp))
 End With
 
        Set d = CreateObject("scripting.dictionary")
        d.CompareMode = vbTextCompare
        For i = 1 To UBound(va, 1)
            d(va(i, 1)) = Empty
        Next
 
        vb = sh1.Range("C1:C" & lastR1)
        For i = 2 To UBound(vb, 1)
           If d.Exists(vb(i, 1)) Then
               If rngCopy Is Nothing Then
                   Set rngCopy = sh1.Rows(i)
               Else
                   Set rngCopy = Union(rngCopy, sh1.Rows(i))
               End If
           End If
        Next
 
    If Not rngCopy Is Nothing Then
       rngCopy.Copy Destination:=sh2.Cells(lastR2, 1)
    End If
End Sub
 
Upvote 0
This should be quite fast:
VBA Code:
Public Sub FindAll()
    Dim rv As Range, f As Range, rng As Range, sh1 As Range, sh2 As Range
    Dim addr As String, strSearch1 As String, strSearch2 As String
    Dim lastR1 As Long, lastR2 As Long

    strSearch1 = "teststring1"
    strSearch2 = "teststring2"
    Set sh1 = ActiveSheet
    Set sh2 = Worksheets("Sheet2")
    lastR1 = sh1.Range("C" & Rows.Count).End(xlUp).Row
    lastR2 = sh2.Range("A" & Rows.Count).End(xlUp).Row + 1
    Set rng = sh1.Range("C2:C" & lastR1)
 
    Set f = rng.Find(what:=strSearch1, after:=rng.Cells(rng.Cells.Count), _
        LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, _
        SearchDirection:=xlNext, MatchCase:=False)
    If Not f Is Nothing Then addr = f.Address()
    Do Until f Is Nothing
        If rv Is Nothing Then
            Set rv = f.EntireRow
        Else
            Set rv = Union(rv, f.EntireRow)
        End If
        Set f = rng.FindNext(after:=f)
        If f.Address() = addr Then Exit Do
    Loop
    Set f = rng.Find(what:=strSearch2, after:=rng.Cells(rng.Cells.Count), _
        LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, _
        SearchDirection:=xlNext, MatchCase:=False)
    If Not f Is Nothing Then addr = f.Address()
    Do Until f Is Nothing
        If rv Is Nothing Then
            Set rv = f.EntireRow
        Else
            Set rv = Union(rv, f.EntireRow)
        End If
        Set f = rng.FindNext(after:=f)
        If f.Address() = addr Then Exit Do
    Loop

  If Not rv Is Nothing Then
    rv.Copy
    sh2.Cells(lastR2, 1).Insert Shift:=xlDown
  End If
 
End Sub
 
Last edited by a moderator:
Upvote 0
Try this:

Put the list say in sheet3 col A


Rich (BB code):
Sub Find_and_copy1()
 Dim sh1 As Worksheet, sh2 As Worksheet, rng As Range, cel As Range
 Dim rngCopy As Range, lastR1 As Long, lastR2 As Long
 Dim strSearch1 As String, strSearch2 As String
 Dim va, vb
 Dim i As Long
 Dim d As Object
 

 Set sh1 = ActiveSheet
 Set sh2 = Worksheets("Sheet2")
 
 lastR1 = sh1.Range("C" & Rows.Count).End(xlUp).Row
 lastR2 = sh2.Range("A" & Rows.Count).End(xlUp).Row + 1
 
 With Sheets("Sheet3")  'put the list here, amend as needed
    va = .Range("A1", .Cells(.Rows.Count, "A").End(xlUp))
 End With
 
        Set d = CreateObject("scripting.dictionary")
        d.CompareMode = vbTextCompare
        For i = 1 To UBound(va, 1)
            d(va(i, 1)) = Empty
        Next
 
        vb = sh1.Range("C1:C" & lastR1)
        For i = 2 To UBound(vb, 1)
           If d.Exists(vb(i, 1)) Then
               If rngCopy Is Nothing Then
                   Set rngCopy = sh1.Rows(i)
               Else
                   Set rngCopy = Union(rngCopy, sh1.Rows(i))
               End If
           End If
        Next
 
    If Not rngCopy Is Nothing Then
       rngCopy.Copy Destination:=sh2.Cells(lastR2, 1)
    End If
End Sub
Hi, thanks for your suggestion. It is working, but it only looks for the first word in the list, and does not continue to the next if the first is not found.
 
Upvote 0
Try this:

Put the list say in sheet3 col A


Rich (BB code):
Sub Find_and_copy1()
 Dim sh1 As Worksheet, sh2 As Worksheet, rng As Range, cel As Range
 Dim rngCopy As Range, lastR1 As Long, lastR2 As Long
 Dim strSearch1 As String, strSearch2 As String
 Dim va, vb
 Dim i As Long
 Dim d As Object
 

 Set sh1 = ActiveSheet
 Set sh2 = Worksheets("Sheet2")
 
 lastR1 = sh1.Range("C" & Rows.Count).End(xlUp).Row
 lastR2 = sh2.Range("A" & Rows.Count).End(xlUp).Row + 1
 
 With Sheets("Sheet3")  'put the list here, amend as needed
    va = .Range("A1", .Cells(.Rows.Count, "A").End(xlUp))
 End With
 
        Set d = CreateObject("scripting.dictionary")
        d.CompareMode = vbTextCompare
        For i = 1 To UBound(va, 1)
            d(va(i, 1)) = Empty
        Next
 
        vb = sh1.Range("C1:C" & lastR1)
        For i = 2 To UBound(vb, 1)
           If d.Exists(vb(i, 1)) Then
               If rngCopy Is Nothing Then
                   Set rngCopy = sh1.Rows(i)
               Else
                   Set rngCopy = Union(rngCopy, sh1.Rows(i))
               End If
           End If
        Next
 
    If Not rngCopy Is Nothing Then
       rngCopy.Copy Destination:=sh2.Cells(lastR2, 1)
    End If
End Sub
Hi, thanks for the code. It works, but only partially. If it find the first word in the list the code will stop. It will not test the second or third word if the first word is not found.
 
Upvote 0
Hi, thanks for your suggestion. It is working, but it only looks for the first word in the list, and does not continue to the next if the first is not found.
Not sure why. Where do you put the list?
It works on my side:
Example:

Book1
CDE
1
2HGriffin
3AMalaki
4GJermaine
5MCayson
6IZachary
7CGabriel
8KAriel
9ZDominik
10XAri
11OErick
12PAdrien
13JZayn
14BRoland
15SGiovanni
16UKamari
17WKellen
18TJedidiah
19Emiliano
20
Sheet1


Result:
Book1
ABCDE
1
2AMalaki
3CGabriel
4KAriel
5JZayn
6
Sheet2


The list:
Book1
AB
1A
2J
3Q
4K
5F
6C
7E
8
Sheet3
 
Upvote 0
Not sure why. Where do you put the list?
It works on my side:
Example:

Book1
CDE
1
2HGriffin
3AMalaki
4GJermaine
5MCayson
6IZachary
7CGabriel
8KAriel
9ZDominik
10XAri
11OErick
12PAdrien
13JZayn
14BRoland
15SGiovanni
16UKamari
17WKellen
18TJedidiah
19Emiliano
20
Sheet1


Result:
Book1
ABCDE
1
2AMalaki
3CGabriel
4KAriel
5JZayn
6
Sheet2


The list:
Book1
AB
1A
2J
3Q
4K
5F
6C
7E
8
Sheet3
I put the list in Sheet3
Not sure why. Where do you put the list?
It works on my side:
Example:

Book1
CDE
1
2HGriffin
3AMalaki
4GJermaine
5MCayson
6IZachary
7CGabriel
8KAriel
9ZDominik
10XAri
11OErick
12PAdrien
13JZayn
14BRoland
15SGiovanni
16UKamari
17WKellen
18TJedidiah
19Emiliano
20
Sheet1


Result:
Book1
ABCDE
1
2AMalaki
3CGabriel
4KAriel
5JZayn
6
Sheet2


The list:
Book1
AB
1A
2J
3Q
4K
5F
6C
7E
8
Sheet3
OK, I found the error, and that is on my side. In the column/cell where the code is looking for the words, there is sometimes a string with several words, and then it does not find it. It will only be found if it is the only word in the cell.
 
Upvote 0
OK, I found the error, and that is on my side. In the column/cell where the code is looking for the words, there is sometimes a string with several words, and then it does not find it. It will only be found if it is the only word in the cell.
So, is it working now? or you need to amend the code to suit?
 
Upvote 0
So, is it working now? or you need to amend the code to suit?
It is working in principle, but the code need to be changed to allow for searching for the "word" in a string with multiple words
 
Upvote 0
It is working in principle, but the code need to be changed to allow for searching for the "word" in a string with multiple words
That's doable, but depends on your data, searching for partial match could have this problem:
Example:
Word to find: car
Find in these 2 sentences:
1. I have a car,
2. This is a card.

You probably just want to match "car" in the first sentence, but it would also match "car" (in "card") in the second sentence.
Could your data have this kind of problem?
If yes, then we need to use regex.
 
Upvote 0

Forum statistics

Threads
1,223,670
Messages
6,173,721
Members
452,528
Latest member
ThomasE

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top