VBA Solution to Search Text and Return Desired Result

plk0507

New Member
Joined
Dec 15, 2021
Messages
18
Office Version
  1. 365
Platform
  1. Windows
Hi,

First-time poster so I want to say thank you in advance for looking at my issue. Below is a sample from my worksheet that is actually hundreds of thousands of lines long.

I'm looking for a solution to search columns J, K, and L for the values in column Y (column y is actually 5-6 thousand lines long). And if it finds the value, return it to column M, separated by a comma.

I've been using the following formula: =TEXTJOIN(", ", TRUE, IF(COUNTIF(J2:L2, "*"&$Y$2:$Y$9&"*"), $Y$2:$Y$9, ""))

My issue with that formula is it also returns partial matches. For example, look at the result in M3. It returned W269 simply because it's a partial match to W2690. On a file with 900 thousand lines, that partial match could repeat itself a few thousand times, and manually fixing it can take days. My other issue is running that formula can take a couple of hours.

My question is, is there a VBA solution to searching this data that will return the desired result without the partial matches? Thank you for your help, I sincerely appreciate it.



Book1.xlsx
ABCDEFGHIJKLMNOPQRSTUVWXY
1Aircraft TypeTail NumberJCNWCE IDWUCHow MalAction TakenWhen Discovered CodeType Maint CodeCorrective ActionDiscrepancyWCE NarrativeHarnessRDIStart DateStop DateLaborBaseUnits ProducedHow Mal ClassBlock NumberHarness Number
2F016D 8900002171 1515502761 62000799XFBVHF OPS CHK C/WVHF AUDIO HARNESS W1654 PART NUMBER H16DW1654-504,W1644 PART NUMBER H16DW1644-514 AND W1844 PART NUMBER H16DW1844-300 REQUIRE REPLACEMENT.VHF AUDIO HARNESS W1654 PART NUMBER H16DW1654-504,W1644 PART NUMBER H16DW1644-514 AND W1844 PART NUMBER H16DW1844-300 REQUIRE REPLACEMENT.W1644, W1654, W184442799.7142799.752KUNSAN1640W1644
3F016D 9000000783 2035105340 630006FSRRECOUP HOURS FOR: SOLDER NEW WAFER ON TO WIRES TO REPAIR W1812-9154J424. PERFORM CONTINUITY CHECK TO ENSURE PROPER CONNECTIONSREF 1F-16CG-2-00GV-00-2***ADD TIME REQ, REF OP#91438*** NSFE FOUND DURING INSTALL OF HARNESS 16DW2690-501 BROKEN PINS WERE FOUND ON W1812-9154J424 T.O./FIG:REF 1F-16CG-2-00GV-00-2***ADD TIME REQ, REF OP#91438*** NSFE FOUND DURING INSTALL OF HARNESS 16DW2690-501 BROKEN PINS WERE FOUND ON W1812-9154J424 T.O./FIG:REF 1F-16CG-2-00GV-00-2W269, W1812, W2690441814418144.3HILL AFB UT1142W1654
4F016D 9000000783 2034904270 630006FSRSOLDER NEW WAFER ON TO WIRES TO REPAIR W1812-9154J424. PERFORM CONTINUITY CHECK TO ENSURE PROPER CONNECTIONSREF 1F-16CG-2-00GV-00-2NSFE FOUND DURING INSTALL OF HARNESS 16DW2690-501 BROKEN PINS WERE FOUND ON W1812-9154J424 T.O./FIG:REF 1F-16CG-2-00GV-00-2NSFE FOUND DURING INSTALL OF HARNESS 16DW2690-501 BROKEN PINS WERE FOUND ON W1812-9154J424 T.O./FIG:REF 1F-16CG-2-00GV-00-2W269, W1812, W269044179441796HILL AFB UT1142W1844
5F016D 8900002166 1505674072 64000799XDDSEE NEW JCN 161896706 FOR UPDATED JOBCOM 2 RADIO TRANSMITS SQUEAL/TONES WHEN MIC IS KEYED, IF VOLUME KNOB IS PAST 3:00 POSITION. VOLUME ANY LOWER AND COM 2 IS INAUDIABLEJOB CREATED TO ORDER AND REPLACE VHF AUDIO HARNESS W1654 PART NUMBER H16DW1654-504,W1644 PART NUMBER H16DW1644-514 AND W1844 PART NUMBER H16DW1844-300.W1644, W1654, W184442563.2542563.292KUNSAN1640W269
6F016D 8800000170 2108891708 69B9870RBBW2690-204-20 R2 IAW 1F-16CG-2-00GV-00-2 SECTION 14PANEL 3434 & 3436 REMOVED TO FOM SEE JCN 210550032001W2690-204-20 SHOOTS OPEN FROM RPS 2382P2/1 TO LVT 2382P12W269, W26902382P12, 2382P2/144286.7144286.731EGLIN AFB FL1140W1812
7F016D 8800000170 21067022814 69B98308RBBFILL PORT HARNESS R2 IAW 1F-16CG-2-00GV-00-2 PARA 14.7MIDS 006,012,029,031,035,056,074,075 MFL'S. TACAN WORKED FINEH16DW2693P4/1 REMOVED FOR REPLACEMENTW269, W269344279.7944280.1324EGLIN AFB FL1140W2690
8F016D 8900002162 21063012810 69B00800SFBREINSTALLED CABLE H16DW2682-600 IAW (PARA 14.8 00GV-2)GUN REQ REM FOR JAMREMOVED CABLE H16DW2682-600 TO FOMW268, W268244263.6744263.712HOLLOMAN1642W268
9F016D 9000000783 2035105370 69000800SSRRECOUP HOURS FOR: INSTALL WIRE HARNESS 16DW2690-501 IN GUN DRUM IAW 16D40730.DOCUMENT STEPS AND TIME OF EACH STEP ON ATTACHED 959***ADD TIME REQ, REF OP#91427*** NSFE WIRE HARNESS 16DW2690-501 FOUND UNINSTALLED. T.O./FIG:IAW 16D40730***ADD TIME REQ, REF OP#91427*** NSFE WIRE HARNESS 16DW2690-501 FOUND UNINSTALLED. T.O./FIG:IAW 16D40730W269, W269044181441812.1HILL AFB UT1642W2682
10F016D 9000000783 2034904290 69000800SSRINSTALL WIRE HARNESS 16DW2690-501 IN GUN DRUM IAW 16D40730.DOCUMENT STEPS AND TIME OF EACH STEP ON ATTACHED 959NSFE WIRE HARNESS 16DW2690-501 FOUND UNINSTALLED. T.O./FIG:IAW 16D40730NSFE WIRE HARNESS 16DW2690-501 FOUND UNINSTALLED. T.O./FIG:IAW 16D40730W269, W269044179441794HILL AFB UT1642
11F016D 8900002167 2007221673 69B0020RFBR2 HARNESS IAW 1F-16CG-2-00GV-00-2 CHAPTER 14238282 P1/4 SMASHED, REQUIRES REPLACEMENTW2690-; 2382P3/3 & 2382P6 INNER WIRE EXPOSED REQUIRE REPLCMENT; 2382P2/1 MISSING GRNDING FSTNER AND 2382P3/3 WORN GRNDING FSTNER NUT REMAIN LOOSE AFTER TIGHTENING PN(H16DW2690-501)W269, W26902382P3/3, 2382P2/1, 2382P643909.543909.8324TULSA1142
Sheet2
 
This ought to do it. I also converted some of the collection use to arrays.

VBA Code:
Sub Harness_Search()

Dim input_data() As Variant, X As Long, Y As Long, output() As String, ITR As Variant, T As Long, _
Z As Long, value() As String, Query() As Variant, row_str As String, Query_CLCTN As New Collection

    Dim Destination_RNG As Range
 
    Const delimiter As String = ", "
 
    With ThisWorkbook.ActiveSheet
 
        input_data = .Range("J2", "L" & .UsedRange.Rows.Count).Value2 'Data from columns J through L
  
        ReDim output(LBound(input_data, 1) To UBound(input_data, 1), 1 To 1)
   
        Query_CLCTN.Add Array("Y", "M") '(Source of codes, output column)
        Query_CLCTN.Add Array("Z", "N")
   
        ReDim Query(1 To Query_CLCTN.Count)
   
        For Z = LBound(Query) To UBound(Query)
  
            ITR = Query_CLCTN(Z)
       
            harness_codes = .Range(ITR(0) & "2", .Cells(.Rows.Count, ITR(0)).End(xlUp)).Value2
            Set Destination_RNG = .Range(ITR(1) & "2", ITR(1) & .UsedRange.Rows.Count)
       
            Query(Z) = Array(harness_codes, Destination_RNG, output)
      
        Next Z
  
    End With
 
    Set Destination_RNG = Nothing
    Set Query_CLCTN = Nothing
    Erase harness_codes
 
    For X = LBound(input_data, 1) To UBound(input_data, 1) 'Loop each ROW of columns J through L
 
        row_str = vbNullString
  
        For Y = LBound(input_data, 2) To UBound(input_data, 2) 'Loop each COLUMN from J to L and generate a string to be searched
       
            On Error GoTo String_Concatenation_Error
       
            If Not input_data(X, Y) = Empty Then
                row_str = row_str & "|" & input_data(X, Y)
            End If
       
        Next Y
        On error goto 0
        If Not row_str = vbNullString Then
  
            For T = LBound(Query) To UBound(Query) 'Loop Query
               
                 'Query(T)(0) are the codes being searched for
                 For Z = LBound(Query(T)(0), 1) To UBound(Query(T)(0), 1) 'Loop though each Harness Number from column Y
                     'patterns:
                     'Any string + code + any non-alphanumeric character + Any string(includes empty string)
                     'Any string + code
                   
                     If Not Query(T)(0)(Z, 1) = Empty _
                     And (row_str Like "*" & Query(T)(0)(Z, 1) & "[!A-Za-z0-9]*" _
                         Or row_str Like "*" & Query(T)(0)(Z, 1)) Then
                   
                         Query(T)(2)(X, 1) = Query(T)(2)(X, 1) & IIf(Query(T)(2)(X, 1) = Empty, vbNullString, delimiter) & Query(T)(0)(Z, 1)

                     End If
               
                 Next Z
          
            Next T

        End If
  
        If X Mod 3000 = 0 Then DoEvents 'Allow user interaction with Excel every 3000 loops
  
    Next X

With ThisWorkbook.ActiveSheet
    For Each ITR In Query
        ITR(1).Value2 = ITR(2)
    Next ITR
End With

MsgBox "Search Completed."

Exit Sub

String_Concatenation_Error:
 
    If iserror( input_data(X, Y))  Then
        Resume Next
    Else
        MsgBox "An error occured on row " & X + 1 & vbNewLine & vbNewLine & _
        "Description: " & Err.Description & vbNewLine & vbNewLine & _
        "Type: " & TypeName(input_data(X, Y))
    End If
 
End Sub
 
Last edited:
Upvote 0
Solution

Excel Facts

Enter current date or time
Ctrl+: enters current time. Ctrl+; enters current date. Use Ctrl+: Ctrl+; Enter for current date & time.
This ought to do it. I also converted some of the collection use to arrays.

VBA Code:
Sub Harness_Search()

Dim input_data() As Variant, X As Long, Y As Long, output() As String, ITR As Variant, T As Long, _
Z As Long, value() As String, Query() As Variant, row_str As String, Query_CLCTN As New Collection

    Dim Destination_RNG As Range
 
    Const delimiter As String = ", "
 
    With ThisWorkbook.ActiveSheet
 
        input_data = .Range("J2", "L" & .UsedRange.Rows.Count).Value2 'Data from columns J through L
 
        ReDim output(LBound(input_data, 1) To UBound(input_data, 1), 1 To 1)
  
        Query_CLCTN.Add Array("Y", "M") '(Source of codes, output column)
        Query_CLCTN.Add Array("Z", "N")
  
        ReDim Query(1 To Query_CLCTN.Count)
  
        For Z = LBound(Query) To UBound(Query)
 
            ITR = Query_CLCTN(Z)
      
            harness_codes = .Range(ITR(0) & "2", .Cells(.Rows.Count, ITR(0)).End(xlUp)).Value2
            Set Destination_RNG = .Range(ITR(1) & "2", ITR(1) & .UsedRange.Rows.Count)
      
            Query(Z) = Array(harness_codes, Destination_RNG, output)
     
        Next Z
 
    End With
 
    Set Destination_RNG = Nothing
    Set Query_CLCTN = Nothing
    Erase harness_codes
 
    For X = LBound(input_data, 1) To UBound(input_data, 1) 'Loop each ROW of columns J through L
 
        row_str = vbNullString
 
        For Y = LBound(input_data, 2) To UBound(input_data, 2) 'Loop each COLUMN from J to L and generate a string to be searched
      
            On Error GoTo String_Concatenation_Error
      
            If Not input_data(X, Y) = Empty Then
                row_str = row_str & "|" & input_data(X, Y)
            End If
      
        Next Y
        On error goto 0
        If Not row_str = vbNullString Then
 
            For T = LBound(Query) To UBound(Query) 'Loop Query
              
                 'Query(T)(0) are the codes being searched for
                 For Z = LBound(Query(T)(0), 1) To UBound(Query(T)(0), 1) 'Loop though each Harness Number from column Y
                     'patterns:
                     'Any string + code + any non-alphanumeric character + Any string(includes empty string)
                     'Any string + code
                  
                     If Not Query(T)(0)(Z, 1) = Empty _
                     And (row_str Like "*" & Query(T)(0)(Z, 1) & "[!A-Za-z0-9]*" _
                         Or row_str Like "*" & Query(T)(0)(Z, 1)) Then
                  
                         Query(T)(2)(X, 1) = Query(T)(2)(X, 1) & IIf(Query(T)(2)(X, 1) = Empty, vbNullString, delimiter) & Query(T)(0)(Z, 1)

                     End If
              
                 Next Z
         
            Next T

        End If
 
        If X Mod 3000 = 0 Then DoEvents 'Allow user interaction with Excel every 3000 loops
 
    Next X

With ThisWorkbook.ActiveSheet
    For Each ITR In Query
        ITR(1).Value2 = ITR(2)
    Next ITR
End With

MsgBox "Search Completed."

Exit Sub

String_Concatenation_Error:
 
    If iserror( input_data(X, Y))  Then
        Resume Next
    Else
        MsgBox "An error occured on row " & X + 1 & vbNewLine & vbNewLine & _
        "Description: " & Err.Description & vbNewLine & vbNewLine & _
        "Type: " & TypeName(input_data(X, Y))
    End If
 
End Sub
When I put that into VBA, there isn't a macro to run.
 
Upvote 0
When I put that into VBA, there isn't a macro to run.
Ensure that
VBA Code:
If iserror( input_data(X, Y))  Then
is the first line in the error handler at the bottom. I did an edit shortly after posting. If it still doesn't work then try Debug>Compile and tell me if something is wrong
 
Upvote 0
Ensure that
VBA Code:
If iserror( input_data(X, Y))  Then
is the first line in the error handler at the bottom. I did an edit shortly after posting. If it still doesn't work then try Debug>Compile and tell me if something is wrong
Holy cow, it worked! I'm going to try and duplicate it on a couple of other files this afternoon and I'll let you know.
 
Upvote 0
MoshiM - Thank you. I appreciate your efforts to help me solve this problem. I'm jealous of your ability to write code; that's super cool.

Akuini - Thank you as well...I see MoshiM used something from your code to solve a problem. And I'm going to try your solution as well and let you know how it goes.
 
Upvote 0

Forum statistics

Threads
1,215,046
Messages
6,122,849
Members
449,096
Latest member
Erald

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