Question about VBA macro using Index Match with 2 criteria

kiri

New Member
Joined
Mar 7, 2023
Messages
5
Office Version
  1. 2021
Platform
  1. Windows
Hello

I am trying to use VBA to get values from 1 worksheet into another with index match based on 2 criteria. The problem is that i need the script to return a value only when BOTH criteria find a match. My code appears to return a value even when only one of my criteria matches. My knowledge of VBA is very limited, im learning as i go, and i dont know why its behaving this way. Bellow is the code that i got so far.

I am also uploading 2 minisheets (because im working on a workbook with 2 worksheets). The first minisheet represents the "cart" in my code and the second the"STK".

If you look in the first minisheet in the last row of column P it returned a value (1.65) from row 43 of the 2nd minisheet where only 1 of my criteria match. My second criteria which in this case should have a value of "1" doesnt match the value in cell E43 which has a value of "4".

How can i get my code to only write a value if both of the criteria match?

I hope i managed to describe my issue well and i thank you in advance for your time, if you need more info let me know.


VBA Code:
Sub indexmatchsheets()

    Dim cart As Worksheet, STK As Worksheet
    Dim cartLastRow As Long, STKLastRow As Long, x As Long
    Dim Indexrng As Range, matchrng As Range, matchrng1 As Range
    
    Set STK = ThisWorkbook.Worksheets("STK8331.RPT")
    Set cart = ThisWorkbook.Worksheets("oc_product")
    
    STKLastRow = STK.Range("D" & Rows.Count).End(xlUp).Row
    cartLastRow = cart.Range("A" & Rows.Count).End(xlUp).Row
    
    Set Indexrng = STK.Range("D2:D" & STKLastRow)
    Set matchrng = STK.Range("A2:A" & STKLastRow)
    Set matchrng1 = STK.Range("E2:E" & STKLastRow)
    
    For x = 2 To cartLastRow
        On Error Resume Next
        cart.Range("P" & x).Value = Application.WorksheetFunction.Index(Indexrng, _
        Application.WorksheetFunction.Match(cart.Range("D" & x).Value, matchrng, 0), _
        Application.WorksheetFunction.Match(cart.Range("T2").Value, matchrng1, 0))
        
    Next x
    


End Sub

test.xlsm
ABCDEFGHIJKLMNOP
257LE730094LE730094LE730094206513.173.17
358LE730091LE730091LE730091206512.42.4
459LE730037LE730037LE7300372065110.310.84
551LE730076LE730076LE7300762006516.516.51
652LE730056LE730056LE730056206518.49.66
753LE730057LE730057LE7300572065118.2519.33
854LE730095LE730095LE7300952065122
955LE730096LE730096LE730096206513.33.3
1056LE730092LE730092LE730092206512.62.6
11115FLA2FLA201100006010.550
1263LE684603LE684603LE68460320651310
1362LE730012LE730012LE730012406517.898.32
1460LE730023LE730023LE730023206519.19.8
1561LE730029LE730029LE730029206512121
1649LE684604LE684604LE68460420651420
1750LE730066LE730066LE7300662006513.33.3
1864LE684636LE684636LE68463620651370
1965LE684570LE684570LE68457020651300
2066LE684620LE684620LE68462020651390
2167LE684602le684602LE68460220651380
2268LE684553LE684553LE68455320651230
2369LE684554LE684554LE68455420651390
2470LE572035LE572035LE572035206514.50
2571LE572005LE502005LE572005206514.20
2672LE572341LE572341LE572341206511.50
2773LE572220LE572220LE57222020651220
2874CU9000SCU9000SCU9000S20061114.230
2975CU7000SCU7000SCU7000S20061113.160
3076CU9903CU9903CU990310611117.320
3179LE730000LE730000LE7300002006511.831.65
oc_product


test.xlsm
ABCDE
1LE730000SWITCH 10A 1G 1W SYNERGYPCS1.8301
2LE730001SWITCH 10A 1G 2W SYNERGYPCS2.2001
3LE730002SWITCH 10A 2G 2W SYNERGYPCS4.2001
4LE730003SWITCH 10A 3G 2W SYNERGYPCS6.3001
5LE730004SWITCH 10A 4G 2W SYNERGYPCS11.3001
6LE730005SWITCH 10A INTER SYNERGYPCS6.5001
7LE730006SWITCH 10A 6G 2W SYNERGYPCS16.7201
8LE730011SWITCH PRESS SYNERGYPCS4.0001
9LE730012SWITCH 20A DP SYNERGYPCS8.3201
10LE730023SWITCH 45A DP WITH NEON SYN COOKER 1GPCS9.8001
11LE730029COOKER LEGRAND WITH SOCKET SYNERGYPCS21.0001
12LE730033FUSE CONN UNIT NO SWIT SYNERPCS11.6801
13LE730037SWITCH FUSE CONN UNIT SYNERGYPCS10.8401
14LE730040SOCKET TV 1G PASS THROUGH MALE SYNEPCS4.9001
15LE730046DIMMER 1G 2W 250W SYNERGYPCS28.0001
16LE730047DIMMER 2G 2W 250W SYNERGYPCS64.0001
17LE730048DIMMER 1G 2W 400W SYNERGYPCS38.0001
18LE730050SOCKET TEL.MASTER 1G SYNERGYPCS7.5001
19LE730051SOCKET TEL.SECONDARY 1G SYNERGPCS6.3001
20LE730056SOCKET CAT6 RJ45 1G SYNERGYPCS9.6601
21LE730057SOCKET CAT6 RJ45 2G SYNERGYPCS19.3301
22LE730058LAMP RED LED SYNERGYPCS2.4501
23LE730066SOCKET OUTLET 1G SYNERGYPCS3.3001
24LE730067SOCKET OUTL 1G SYNER NON STANDPCS10.9201
25LE730068SOCKET OUTLET 1G 5A UNSWIT SYNERGYPCS7.5601
26LE730070SOCKET OUTLET 2G DP SYNERGYPCS10.7601
27LE730071SOCKET OUTLET 2G DP WITH NEON SYNERGYPCS15.7801
28LE730076SOCKET OUTLET 2G SYNERGYPCS6.5101
29LE730077SOCKET OUTL 2G SYNER NON STANDPCS23.0001
30LE730078SOCKET OUTLET 1G SYNERGY WITH USB CHARGERPCS36.9701
31LE730079SOCKET OUTLET 2G SYNERGY WITH 2 USB CHARGERPCS74.0001
32LE730090SHAVER SOCKET 240/120V SYNERGYPCS50.9001
33LE730091PLATE CARRIER 1G 1MOD SYNERGYPCS2.4001
34LE730092PLATE CARRIER 1G 2MOD SYNERGYPCS2.6001
35LE730094PLATE CARRIER 2G 4MOD SYNERGYPCS3.1701
36LE730095PLATE BLANC 1G SYNERGYPCS2.0001
37LE730096PLATE BLANC 2G SYNERGYPCS3.3001
38370
39Items0
400
410
420
43LE730000PCS1.6504
44LE730001PCS1.9502
45LE730002PCS3.8202
46LE730003PCS5.7002
47LE730004PCS10.2002
48LE730005PCS5.8802
49LE730006PCS15.5002
STK8331.RPT
Cell Formulas
RangeFormula
A38A38=SUBTOTAL(3,A1:A37)
 

Excel Facts

Round to nearest half hour?
Use =MROUND(A2,"0:30") to round to nearest half hour. Use =CEILING(A2,"0:30") to round to next half hour.
VBA Code:
Sub indexmatchsheets()

    Dim cart As Worksheet, STK As Worksheet
    Dim cartLastRow As Long, STKLastRow As Long, x As Long
    Dim Indexrng As Range, matchrng As Range, matchrng1 As Range
   
    Set STK = ThisWorkbook.Worksheets("STK8331.RPT")
    Set cart = ThisWorkbook.Worksheets("oc_product")
   
    STKLastRow = STK.Range("D" & Rows.Count).End(xlUp).Row
    cartLastRow = cart.Range("A" & Rows.Count).End(xlUp).Row
   
    Set Indexrng = STK.Range("D2:D" & STKLastRow)
    Set matchrng = STK.Range("A2:A" & STKLastRow)
    Set matchrng1 = STK.Range("E2:E" & STKLastRow)

    With Application.WorksheetFunction
    For x = 2 To cartLastRow
        On Error Resume Next
        cart.Range("P" & x).Value = .Index(Indexrng, .Match(cart.Range("D" & x).Value, matchrng, 0) + .Match(cart.Range("T2").Value, matchrng1, 0) - 1)
    Next x
    End With

End Sub
 
Upvote 0
Hi,
You could test following
VBA Code:
Sub IndexMatchSheets()

Dim cart As Worksheet, STK As Worksheet
Dim cartLastRow As Long, STKLastRow As Long, x As Long
Dim Indexrng As Range, matchrng As Range, matchrng1 As Range
Dim res1, res2
    
    Set STK = ThisWorkbook.Worksheets("STK8331.RPT")
    Set cart = ThisWorkbook.Worksheets("oc_product")
    
    STKLastRow = STK.Range("D" & Rows.Count).End(xlUp).Row
    cartLastRow = cart.Range("A" & Rows.Count).End(xlUp).Row
    
    Set Indexrng = STK.Range("D2:D" & STKLastRow)
    Set matchrng = STK.Range("A2:A" & STKLastRow)
    Set matchrng1 = STK.Range("E2:E" & STKLastRow)
    
    For x = 2 To cartLastRow
        res1 = Application.WorksheetFunction.Match(cart.Range("D" & x).Value, matchrng, 0)
        res2 = Application.WorksheetFunction.Match(cart.Range("T2").Value, matchrng1, 0)
        If Not IsError(res1) And Not IsError(res2) Then
            cart.Range("P" & x).Value = Application.WorksheetFunction.Index(Indexrng, _
            res1, _
            res2)
        End If
    Next x

End Sub
 
Upvote 0
VBA Code:
Sub indexmatchsheets()

    Dim cart As Worksheet, STK As Worksheet
    Dim cartLastRow As Long, STKLastRow As Long, x As Long
    Dim Indexrng As Range, matchrng As Range, matchrng1 As Range
  
    Set STK = ThisWorkbook.Worksheets("STK8331.RPT")
    Set cart = ThisWorkbook.Worksheets("oc_product")
  
    STKLastRow = STK.Range("D" & Rows.Count).End(xlUp).Row
    cartLastRow = cart.Range("A" & Rows.Count).End(xlUp).Row
  
    Set Indexrng = STK.Range("D2:D" & STKLastRow)
    Set matchrng = STK.Range("A2:A" & STKLastRow)
    Set matchrng1 = STK.Range("E2:E" & STKLastRow)

    With Application.WorksheetFunction
    For x = 2 To cartLastRow
        On Error Resume Next
        cart.Range("P" & x).Value = .Index(Indexrng, .Match(cart.Range("D" & x).Value, matchrng, 0) + .Match(cart.Range("T2").Value, matchrng1, 0) - 1)
    Next x
    End With

End Sub
Hi, thank you for the fast reply. I just tested it but it has exactly the same result as my original code.
 
Upvote 0
Hi,
You could test following
VBA Code:
Sub IndexMatchSheets()

Dim cart As Worksheet, STK As Worksheet
Dim cartLastRow As Long, STKLastRow As Long, x As Long
Dim Indexrng As Range, matchrng As Range, matchrng1 As Range
Dim res1, res2
   
    Set STK = ThisWorkbook.Worksheets("STK8331.RPT")
    Set cart = ThisWorkbook.Worksheets("oc_product")
   
    STKLastRow = STK.Range("D" & Rows.Count).End(xlUp).Row
    cartLastRow = cart.Range("A" & Rows.Count).End(xlUp).Row
   
    Set Indexrng = STK.Range("D2:D" & STKLastRow)
    Set matchrng = STK.Range("A2:A" & STKLastRow)
    Set matchrng1 = STK.Range("E2:E" & STKLastRow)
   
    For x = 2 To cartLastRow
        res1 = Application.WorksheetFunction.Match(cart.Range("D" & x).Value, matchrng, 0)
        res2 = Application.WorksheetFunction.Match(cart.Range("T2").Value, matchrng1, 0)
        If Not IsError(res1) And Not IsError(res2) Then
            cart.Range("P" & x).Value = Application.WorksheetFunction.Index(Indexrng, _
            res1, _
            res2)
        End If
    Next x

End Sub
Hi i tested it and i get runtime error "unable to get the match property of the worksheetfunction class on the line "res1 = Application.WorksheetFunction.Match(cart.Range("D" & x).Value, matchrng, 0)".
 
Upvote 0
Doesn't that means exactly what you intended ... i.e. catch the specific case whenever there is no match ... ?
 
Upvote 0
May be, you can test following:
VBA Code:
Sub IndexMatchSheetsV2()

Dim cart As Worksheet, STK As Worksheet
Dim cartLastRow As Long, STKLastRow As Long, x As Long
Dim Indexrng As Range, matchrng As Range, matchrng1 As Range
Dim res1, res2
    
    Set STK = ThisWorkbook.Worksheets("STK8331.RPT")
    Set cart = ThisWorkbook.Worksheets("oc_product")
    
    STKLastRow = STK.Range("D" & Rows.Count).End(xlUp).Row
    cartLastRow = cart.Range("A" & Rows.Count).End(xlUp).Row
    
    Set Indexrng = STK.Range("D2:D" & STKLastRow)
    Set matchrng = STK.Range("A2:A" & STKLastRow)
    Set matchrng1 = STK.Range("E2:E" & STKLastRow)
    
    For x = 2 To cartLastRow
        res1 = Application.WorksheetFunction.Match(cart.Range("D" & x).Value, matchrng, 0)
        If IsError(res1) Then GoTo Line1:
        res2 = Application.WorksheetFunction.Match(cart.Range("T2").Value, matchrng1, 0)
        If IsError(res2) Then GoTo Line1:
            ' No Errors - Perform Index
            cart.Range("P" & x).Value = Application.WorksheetFunction.Index(Indexrng, _
            res1, _
            res2)
Line1:
    Next x

End Sub
 
Upvote 0
Doesn't that means exactly what you intended ... i.e. catch the specific case whenever there is no match ... ?
Now i understand what you did. With your code i get the error and i can see on which line the error. But i im not trying to catch it, i want to skip it.

I dont want it to return a result unless both my criteria find a match. If you see in my first minisheet column P is populated by 0 (zeros) and my code overwrites those 0 with values from the second minisheet. In this case cell P31 of my first minisheet should have been 0 because my second match criteria is not satisfied so it shouldn't add a value there.
In other words what i am trying to achieve is the same as if this was an index match array formula in the workbook. Specifically i want to to with VBA exactly what this formula does:
Excel Formula:
{=INDEX(STK8331.RPT!D1:D126,MATCH(1,(STK8331.RPT!A1:A126=oc_product!D31)*(oc_product!T2=STK8331.RPT!E1:E126),0),1)}

This formula returns #N/A in cell P31. I dont mind it if its "0" or "error" or anything else instead of "#N/A" i just dont want it to grab values from the other worksheet if all the match criteria are not fulfilled.
 
Upvote 0
Have you tested the macro posted in message #7 ... to skip errors ... ?

If it does not produce the expected result, we can always replicate the formula you just posted ...
 
Upvote 0
Have you tested the macro posted in message #7 ... to skip errors ... ?

If it does not produce the expected result, we can always replicate the formula you just posted ...
I forgot to mention it but the macro in message 7 had the same result as the one in message 3, it doesn't skip the error.
In the end yes what i want to do is replicate the formula that i just posted for the entire column P in oc_products. To be honest that's what i thought my original VBA code was doing.
As a formula i just write it in 1 cell and the copy paste it in the rest of the column.
 
Upvote 0

Forum statistics

Threads
1,215,091
Messages
6,123,062
Members
449,089
Latest member
ikke

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