0
votes

I'm trying to make a formula with multiple criteria and wildcards that will return the matching category if found. I think this would be done through a robust Index-Match formula but I'm struggling to get all the criteria into a working formula. I'll explain better with examples...

I have two worksheets, sheet "Import Data" and sheet "Invoice Coding". The formula would be entered on sheet "Import Data", in any column off to the side, say formula goes into Column AD.

Here is the "Import Data" sheet: Import Data

Here is the "Invoicing Coding" sheet (there are over 500 rows and growing, so this is a small screenshot): Invoicing Coding

Step one would be to look for the "ACCT" number (Column O) from "Import Sheet" against the "Invoicing Coding" sheet, which would usually have multiple matches. Step two would then check the corresponding "INV" on the "Import Data" sheet and see if any of the wildcard invoices on sheet "Invoice Coding" match. The return would be the "Category" (Column D) from the "Invoice Coding" sheet.

I'll provide a specific example to try to explain better:

On this line, I want to use column O data, which is the number 50000. Example1

Lookup 50000 on the "Invoice Coding" sheet, which has many results. Example2

Then use the INV from Column D on the previous screenshot, which is... Invoice #

To find if it has a partial match to the wildcards listed in Column C of the "Invoice Coding" sheet screenshot just above.

So in this specific example, the ACCT and INV from the "Import Data" sheet match row 178 on the "Invoice Coding" sheet. The expected result from the formula would be the Category from Column D; Third Party.

Here is what I have for a formula so far, which does not incorporate the partial invoice match using wildcards:

=INDEX('Invoice Coding'!A2:E514,MATCH('Import Data'!O2,'Invoice Coding'!A2:A514,0),4)

This technically returns a Category but it doesn't use the INV # vs the partial INV with wildcard, so the return may be incorrect.

I hope my explanation makes sense. Any advice on if I can enhance an Index-Match formula to include all the required criteria lookups?

As a side note, I would then repeat this formula with slight tweaks to also return the Sub-Category from Column E of the "Invoice Coding" sheet.

Thank you all so much in advance!

1
I'd suggest some simplified sample data to be able to reproduce what you are after. Right of the bet, I'd see possibilities using SUMPRODUCT including ISNUMBER, FIND and the likes.JvdV
You mentioned about the formula: "This technically returns a Category but it doesn't use the INV # vs the partial INV with wildcard". Reason is : you are just matching ACCT 50000 and not the INV WHFD*. So it will always return only the first Category for the given ACCT 50000. For that you also need MATCH('Import Data'!D2,'Invoice Coding'!C2:C514,1) or sumproduct for multiple matches as suggested by JvdVNaresh
Thanks for the feedback. I'm not super familiar with using SUMPRODUCT in a situation like this. Is that likely to be another nested statement within the formula I already have?TBoulz
Willing to expand : "..enhance an Index-Match formula to include all the required criteria lookups?" try this and share the results.. > exceljet.net/formula/index-and-match-with-multiple-criteriap._phidot_
Hey, @p._phidot_ sorry for the delay, had some much needed vacation. I reviewed the link you provided and I THINK I followed it, and made a formula based on the info in the link. However, I am not sure how to include the wildcard search, to match a partial string with an *, so my result is #N/A. My current formula is now an array formula, {=INDEX('Invoice Coding'!E2:E656,MATCH(1,('Import Data'!O2='Invoice Coding'!A2:A656)*('Import Data'!D2='Invoice Coding'!C2:C656),0))} . I appreciate the direction you provided, any idea how to include the wildcard, or if my array formula is all messed up?TBoulz

1 Answers

0
votes

going to answer my own question. We found a solution that works for us through VBA. Originally I was hesitant to approach with VBA because I thought it would take much longer to run compared to a formula, but our solution is quicker than expected, taking about 30 seconds to run through 60,000 rows.

So, our VBA solution:

'***** Declare variables to be used *****
Dim ImportWS As Worksheet, ilastrow As Long, ilooper As Long, FindArray As Variant, CodingWS As Worksheet, clastrow As Long, CodeArray As Variant, clooper As Long, acct As Long, Inv As String, matchfound As Boolean

Application.ScreenUpdating = False
Application.DisplayAlerts = False
    
    'Import Data sheet prep and storing in FindArray
    Set ImportWS = ThisWorkbook.Sheets("Import Data")
    ilastrow = ImportWS.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
    ImportWS.Range("AC1") = "Category"
    ImportWS.Range("AD1") = "Sub Category"
    ImportWS.Range("AE1") = "Billing Name"
    ImportWS.Range("AC2:AE" & ilastrow).ClearContents
    FindArray = ImportWS.Range("AC1:AE" & ilastrow)

    'Storing Coding sheet data into array
    Set CodingWS = ThisWorkbook.Sheets("Invoice Coding")
    clastrow = CodingWS.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
    CodeArray = CodingWS.Range("A1:F" & clastrow)
    
    With ImportWS
        
        'Looping through all rows on Import Data sheet...
        For ilooper = 2 To ilastrow
            
            'Storing GL Acct# and Invoice# for comparison against Coding sheet
            acct = Val(.Range("O" & ilooper))
            Inv = .Range("D" & ilooper)
            
            'matchfound is a boolean that is reset on each row.
            'if a match is found against the Coding sheet it is flipped to true...
            'we stop looking in the following loop...
            'and we commit the cat and subcat to the FindArray variant.
            matchfound = False
            
            'This is our looper for going through the coding table in the following loop.
            clooper = 2
            
            'While we haven't found a match for GL# and Inv...
            'and we haven't reached the end of the table...
            While matchfound = False And clooper <= clastrow
    
                'If acct# matches coding table we perform another check...
                If Val(CodeArray(clooper, 1)) = acct Then
                        
                    '...for partial match on Inv - which accounts for wildcard placement as on the table...

                    If Inv Like CodeArray(clooper, 3) Then
                       'If match is found, matchfound is true, which will stop the next iteration of the loop
                        matchfound = True
                        'and we store the cat and subcat in our FindArray
                        FindArray(ilooper, 1) = CodeArray(clooper, 4)
                        FindArray(ilooper, 2) = CodeArray(clooper, 5)
                        FindArray(ilooper, 3) = CodeArray(clooper, 6)
                    End If
                End If
                
                'If no match, check the next row on the Coding table.
                clooper = clooper + 1
    
            Wend
            
            
        'After we found a match or reached the end of the coding table...
        '...we move on to the next row on the Import Data sheet.
        Next ilooper
        
        'After looping through all rows on the Import Data sheet we commit what we found to columns AC, AD, AE.
        ImportWS.Range("AC1:AE" & ilastrow).Value = FindArray
    
    End With
    
Application.ScreenUpdating = True
Application.DisplayAlerts = True