Userform to search a form by two different criteria for two columns and only bring back results that match both.

Kiyoshi

New Member
Joined
Jan 5, 2017
Messages
4
I've modified the code provided in this thread by Warship to make data entry userforms that allow our staff to search through an Excel file in which we keep a database of customer information. It produces a list of all results that match any one of the three searching criteria entered, and by clicking on the correct entry, puts the information into the userform so that it's quicker for those doing data entry to enter interactions with certain customers. Searching with the following variables: First Name: John and Last Name: Smith, I would get a list of all people with the first name John AND all people with the last name Smith. For example, it might produce the following list:

BillyJohn Smith
JoJohn Abe
John Abraham
Johnny Birch
Johnson Carver
John Smith
Johnathan Smith
Johnathan Smithsonian

Robert Smith
Sam Smith
Tyler Smith
Zach Smithy

Our database is and very likely will remain small enough for this to be entirely functional for the next decade or so, but I'm interested in whether it might be possible to search by the first and the last name such that it only finds names that match both. So from the above list, *if* both fields have something in them (<> "") I'd like it to provide only the names in blue in the above list.

As an addendum that may be relevant to the search criteria question, some customers have data in Column A that notes if there's something a worker may need to know while dealing with them (such as past failures to pay, other reasons to contact management before finalizing an order). Would it be possible to make the listbox display results that have any data in a given Column (specifically in this case, column A) differently, say with a yellow or pink background, etc.?

Here's the code as I have it now, with the section in ##### where I suppose a search by first and last name (dual criteria matches only) might go.

Code:
Private Sub ButtonSearch_Click()

    'Exit form if search fields are blank.
    If DataFirstName = "" And DataLastName = "" And DataIDNumber = "" Then
        MsgBox ("Needs at least a first name, last name, or an ID Number.")
        Exit Sub
    End If


'Declare Variables for Search Function
Dim rgData As Range
Dim rgResults As Range
Dim ListRow As Long
Dim SkipEvent As Boolean
Dim shData As Worksheet


Dim shCurrent As Worksheet
Dim shResults As Worksheet
Dim found As Range
Dim firstFound As String
Dim SrchCol_1 As String
Dim SrchCol_2 As String
Dim SrchCol_3 As String
Dim r As Long




'Stops screen updating while working with DataBase File.
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False
    
    'Open DataBase File workbook, then sets it as the active workbook for the indented portion of code in order to reference it.
    Workbooks.Open Filename:="C:\DataBase.xls", UpdateLinks:=True, ReadOnly:=True
    Set wbBook = Workbooks("DataBase.xls")
    'Hides DataBase from Taskbar
    'ActiveWindow.Visible = False
    
        Set shData = Sheets("DataBase")
        Set rgData = shData.Cells.CurrentRegion
        Set rgData = rgData.Offset(1, 0).Resize(rgData.Rows.Count - 1, rgData.Columns.Count)
        Set shCurrent = ActiveSheet
    
        'Keep errors from popping up or interrupting while cleaning out possible past Results sheets.
        Application.DisplayAlerts = False
        On Error Resume Next
        'Delete Results sheet which shouldn't exist, just in case it does.
        Sheets("Results").Delete
        On Error GoTo 0
        'Turn back on error notifs.
        Application.DisplayAlerts = True
        'Add Results Sheet after the last of however many sheets there are.
        Sheets.Add after:=Sheets(Sheets.Count)
        ActiveSheet.Name = "Results"
        Set shResults = Sheets("Results")
        With shResults
            .Cells(1, 1) = "DataRow" 'Needed for coding/debug purposes. Set width to 0 in listbox properties.
            .Cells(1, 2) = "Call Management"
            .Cells(1, 3) = "Contact Method Preferred"
            .Cells(1, 4) = "Street"
            .Cells(1, 5) = "Zip, City, State"
            .Cells(1, 6) = "First"
            .Cells(1, 7) = "Last"
            .Cells(1, 8) = "ID#"
            .Cells(1, 9) = "Company Name"
            .Cells(1, 10) = "Last Contract"
            .Cells(1, 11) = "Header 10"
            .Cells(1, 12) = "Age"
            .Cells(1, 13) = "Race"
            .Cells(1, 14) = "County"
            .Cells(1, 15) = "Phone"
            .Cells(1, 16) = "Times Servicing"
        End With
        
        'columns to search through
        SrchCol_1 = "E" 'First Name
        SrchCol_2 = "F" 'Last Name
        SrchCol_3 = "G" 'ID Number
         ' ???? Added to try to make it work.
        SrchCol_4 = "E:F" 'First and Last
        
        'Unselects any listbox selections to prevent errors upon clearing out the data for new search.
        ListBoxSearchResults.ListIndex = -1
        
        r = 1
        'Search First Name
        If DataFirstName <> "" And DataLastName = "" Then
            With rgData.Columns(SrchCol_1)
                'Find whatever's in first name, within the range specified as rgData, with partial finds allowed.
                Set found = .Find(DataFirstName, rgData.Cells(rgData.Rows.Count, SrchCol_1))
                If Not found Is Nothing Then
                    firstFound = found.Address
                    Do 'Paste the found data in the sheet, move the data to the right to add next finds. Dakara Itta
                        r = r + 1
                        found.EntireRow.Copy shResults.Cells(r, 1)
                        shResults.Cells(r, 1).Insert Shift:=xlToRight
                        shResults.Cells(r, 1) = found.Row
                        Set found = .FindNext(found)
                    Loop While Not found Is Nothing And found.Address <> firstFound
                End If
            End With
        End If
        
        'Search Last Name
        If DataLastName <> "" And DataFirstName = "" Then

            With rgData.Columns(SrchCol_2)
                Set found = .Find(DataLastName, rgData.Cells(rgData.Rows.Count, SrchCol_2))
                If Not found Is Nothing Then
                    firstFound = found.Address
                    Do
                        r = r + 1
                        found.EntireRow.Copy shResults.Cells(r, 1)
                        shResults.Cells(r, 1).Insert Shift:=xlToRight
                        shResults.Cells(r, 1) = found.Row
                        Set found = .FindNext(found)
                    Loop While Not found Is Nothing And found.Address <> firstFound
                End If
            End With
        End If
        
[COLOR=#0000ff]       'Search First and Last Name[/COLOR]
[COLOR=#0000ff]       If DataFirstName <> "" And DataLastName <> "" Then 'Only records that have some connection to both names.[/COLOR]
[COLOR=#0000ff]           With rgData.Columns(SrchCol_4)[/COLOR]
[COLOR=#0000ff]           ' ##### I know such a thing as the below code won't work.[/COLOR]
[COLOR=#0000ff]           Set found = .Find(DataFirstName, rgData.Cells(rgData.Rows.Count, SrchCol_1)) And .Find(DataLastName, rgData.Cells(rgData.Rows.Count, SrchCol_2))[/COLOR]
[COLOR=#0000ff]           ' #########[/COLOR]
[COLOR=#0000ff]        If Not found Is Nothing Then[/COLOR]
[COLOR=#0000ff]                   firstFound = found.Address[/COLOR]
[COLOR=#0000ff]                   Do[/COLOR]
[COLOR=#0000ff]                       r = r + 1[/COLOR]
[COLOR=#0000ff]                       found.EntireRow.Copy shResults.Cells(r, 1)[/COLOR]
[COLOR=#0000ff]                       shResults.Cells(r, 1).Insert Shift:=xlToRight[/COLOR]
[COLOR=#0000ff]                       shResults.Cells(r, 1) = found.Row[/COLOR]
[COLOR=#0000ff]                       Set found = .FindNext(found)[/COLOR]
[COLOR=#0000ff]                   Loop While Not found Is Nothing And found.Address <> firstFound[/COLOR]
[COLOR=#0000ff]               End If[/COLOR]
[COLOR=#0000ff]           End With[/COLOR]
[COLOR=#0000ff]       End If[/COLOR]
            
        'Search ID Number
        If DataIDNumber <> "" Then
            With rgData.Columns(SrchCol_3)
                Set found = .Find(DataIDNumber, rgData.Cells(rgData.Rows.Count, SrchCol_3))
                If Not found Is Nothing Then
                    firstFound = found.Address
                    Do
                        r = r + 1
                        found.EntireRow.Copy shResults.Cells(r, 1)
                        shResults.Cells(r, 1).Insert Shift:=xlToRight
                        shResults.Cells(r, 1) = found.Row
                        Set found = .FindNext(found)
                    Loop While Not found Is Nothing And found.Address <> firstFound
                End If
            End With
        End If
        If r = 1 Then
            ListBoxSearchResults.RowSource = ""
            MsgBox "No Matches Found'."
        Else
            Set rgResults = shResults.Cells.CurrentRegion
            Set rgResults = rgResults.Offset(1, 0).Resize(rgResults.Rows.Count - 1, rgResults.Columns.Count)
            'Remove duplicates in the first and last name columns (5, 6).
            rgResults.RemoveDuplicates Columns:=Array(5, 6), Header:=xlNo
            Set rgResults = shResults.Cells.CurrentRegion
            Set rgResults = rgResults.Offset(1, 0).Resize(rgResults.Rows.Count - 1, rgResults.Columns.Count)
            ActiveWorkbook.Names.Add Name:="rgResults", RefersTo:=rgResults
            ListBoxSearchResults.RowSource = "rgResults"
        End If
    
    shCurrent.Activate
    Application.ScreenUpdating = True


'Turn on Screen Updating once search is finished.
Application.ScreenUpdating = True
Application.DisplayAlerts = True


'Activates Intake Form Again
ThisWorkbook.Activate

There's a comment note before almost everything because I'm extremely new to Excel VBA (started 9 days ago today) and want to understand the code I'm writing. I've found the examples on this forum extremely helpful in making our data entry processes much less cumbersome. Therefore, if you have suggestions to make any code cleaner or better, I also welcome any advice or teaching you may have. Thank you.
 

Excel Facts

Why does 9 mean SUM in SUBTOTAL?
It is because Sum is the 9th alphabetically in Average, Count, CountA, Max, Min, Product, StDev.S, StDev.P, Sum, VAR.S, VAR.P.

Forum statistics

Threads
1,223,228
Messages
6,170,871
Members
452,363
Latest member
merico17

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