VBA Code Error Unable to get the Match property of the WorksheetFunction class

Jiraya_00

New Member
Joined
Oct 18, 2024
Messages
13
Office Version
  1. 365
Platform
  1. Windows
Hi Everyone,

I'm trying to create a macro that will run through a set of column headers and look for a specific header ("CMA - ERP Variance") and calculate a simple formula for all the cells within that column header. However, I'm running into an error with my code as I get the "Run-time error '1004': Unable to get the Match property of the WorksheetFunction class."

Can anyone help me debug this error and let me know what I'm doing wrong? My code is listed below. Thanks for all the help!

VBA Code:
Sub Test_MatchReplace()

Dim TestHeader As Long
Dim TestCel As Range, TestCel2 As Range, TestCel3 As Range, TestHeader2 As Range, TestURange As Range
Dim ws As Worksheet

Set ws = ShTest

 With Application
    .StatusBar = "Your macro is running"
    .ScreenUpdating = False
    .DisplayAlerts = False
    .Calculation = xlCalculationManual
    
 End With
 
' To find and replace certain original headers on test data report
 TestHeader = WorksheetFunction.Match("Amount", ShTest.Rows(1), 0)
    Columns(TestHeader).Select
        Selection.Replace What:="Amount", Replacement:="CMA Amount", lookat:=xlWhole _
        , SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
        ReplaceFormat:=False, FormulaVersion:=xlReplaceFormula2
        
 TestHeader = WorksheetFunction.Match("Balance", ShTest.Rows(1), 0)
    Columns(TestHeader).Select
        Selection.Replace What:="Balance", Replacement:="CMA Balance", lookat:=xlWhole _
            , SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
            ReplaceFormat:=False, FormulaVersion:=xlReplaceFormula2
 
' To create a formula for the "CMA - ERP Variance" column
 TestHeader2 = ShTest.Range(Cells(1, 1), Cells(1, ShTest.Cells(1, Columns.Count).End(xlToLeft).Column))
    
    For Each TestCel In TestHeader2
        If TestCel.Value = "CMA - ERP Variance" Then
            For Each TestCel2 In ShTest.Range("M2:M" & Cells(Rows.Count, "M").End(xlUp).Row)
                If Not IsEmpty(TestCel2.Value) Then
                    TestCel2.Offset(, 2).Formula = "=(RC[-2]-RC[-1])"
                Else
                    TestCel2.Offset(, 2).Value = 0
                End If
            Next TestCel2
        End If
    Next TestCel
 
' To highlight any cells within the "CMA - ERP Variance" column that has a value not equal to 0

 With ShTest
    Set TestURange = .UsedRange
    Set TestURange = .Range("A2").Resize(RowSize:=TestURange.Rows.Count - 1, ColumnSize:=TestURange.Columns.Count)
    For Each TestCel3 In TestURange
        If TestCel3.Column = 15 And TestCel3.Value <> 0 Then
            TestCel3.Interior.ColorIndex = 6
        End If
    Next TestCel3
 End With
 
 With Application
    .StatusBar = ""
    .ScreenUpdating = True
    .DisplayAlerts = True
    .Calculation = xlCalculationAutomatic
    .CutCopyMode = False
    
 End With

End Sub
 

Attachments

  • Screenshot 211944.png
    Screenshot 211944.png
    96.8 KB · Views: 13

Excel Facts

Format cells as currency
Select range and press Ctrl+Shift+4 to format cells as currency. (Shift 4 is the $ sign).
Hi and welcome to MrExcel

I suppose the error is in this line and that is because, according to your image, the data "Amount" does not exist in row 1.
VBA Code:
TestHeader = WorksheetFunction.Match("Amount", ShTest.Rows(1), 0)

To avoid this error you can use the find method.
The code can be simplified like this:

VBA Code:
Sub Test_MatchReplace()
  Dim f As Range, c As Range
  
  Application.ScreenUpdating = False
  
  ' To find and replace certain original headers on test data report
    Set f = ShTest.Range("1:1").Find("Amount", , xlValues, xlWhole, , , False)
    If Not f Is Nothing Then f.Value = "CMA Amount"
    Set f = ShTest.Range("1:1").Find("Balance", , xlValues, xlWhole, , , False)
    If Not f Is Nothing Then f.Value = "CMA Balance"
  
  ' To create a formula for the "CMA - ERP Variance" column and highlight cell not equal to 0
    Set f = ShTest.Range("1:1").Find("CMA - ERP Variance", , xlValues, xlWhole, , , False)
    If Not f Is Nothing Then
      With f.Offset(1).Resize(ShTest.Range("M" & Rows.Count).End(3).Row - 1)
        .Formula = "=M2-N2"
        For Each c In .Cells
          If c.Value <> 0 Then
            c.Interior.ColorIndex = 6
          End If
        Next
      End With
    End If

  Application.ScreenUpdating = True
End Sub

----- --
Let me know the result and I'll get back to you as soon as I can.
Sincerely
Dante Amor
----- --
 
Upvote 1
Solution
Welcome to the MrExcel board!

My code is listed below.
Is that really your code?
If it is, it should never get to the error you mention as it will error at the highlighted line below because ShTest has not been set to anything.

Rich (BB code):
Sub Test_MatchReplace()

Dim TestHeader As Long
Dim TestCel As Range, TestCel2 As Range, TestCel3 As Range, TestHeader2 As Range, TestURange As Range
Dim ws As Worksheet

Set ws = ShTest

BTW, this line is also not a valid line
VBA Code:
TestHeader2 = ShTest.Range(Cells(1, 1), Cells(1, ShTest.Cells(1, Columns.Count).End(xlToLeft).Column))
Since TestHeader2 is declared as a Range, the line should be ..
Rich (BB code):
Set TestHeader2 = ShTest.Range(Cells(1, 1), Cells(1, ShTest.Cells(1, Columns.Count).End(xlToLeft).Column))
.. and that line would still only work if ShTest (whatever that is) is the ActiveSheet.

As Dante has said, "Amount" is not found in row 1 of your image - but perhaps your image was taken after the code had already been run or part run and "Amount" had already been replaced by "CMA Amount"?

I have not checked the code any further as I think we need your actual code and confirmation of which line causes the error.

It would also be helpful for our testing if you could provide the sample data with XL2BB rather than as an image that we cannot copy from.
 
Upvote 0
Hello Dante & Peter,

Thank you so much for the feedback! You both are absolutely correct as my code was looking for the two column headers ("Amount" and "Balance") that no longer exists because the first couple lines of the code already found and replaced them.

Dante, after plugging in your code, I no longer run into the error message as I guess it doesn't matter if the two original column headers were there or not. If they are there, then they will be replaced; if not, the code simply moves onto the next line, which is fanstastic!

I did have a question regarding this line of code right here:

Rich (BB code):
With TestFind.Offset(1).Resize(ShTest.Range("M" & Rows.Count).End(3).Row - 1)

Why is it "End(3).Row - 1" and not "End(xlUp).Row"? How will the code know to only fill up the column "CMA - ERP Variance" all the way to last cell within the used range/current region and not autofill it all the way to last cell on the worksheet?
 
Upvote 0
Regarding your question, End(3) is the equivalent of End(xlUp). Using 3 is regarded as being undocumented and I would suggest that you stick with using xlUp.
Because that line is not using Range(fromCell, toCell) but using Range(fromCell).Resize(no of rows required) the syntax is slightly different since the no of rows required is the Last Row in Column M minus the Heading Row no which happens to be 1.
This would be more generic in case the heading was not on row 1
Rich (BB code):
With TestFind.Offset(1).Resize(ShTest.Range("M" & Rows.Count).End(xlUp).Row - TestFind.Row)

Discussion on using End(3) here:
 
Upvote 0
Dante, after plugging in your code, I no longer run into the error message as I guess it doesn't matter if the two original column headers were there or not. If they are there, then they will be replaced; if not, the code simply moves onto the next line, which is fanstastic!
Im glad to help you and thanks for your feedback.


Answering your question:
Why is it "End(3).Row - 1" and not "End(xlUp).Row"?
The number 3 is the numeric value for the xlUp parameter:

1676472239346.png

You can use xlUp or 3:
xlDown = 4​
xlToLeft = 1​
xlToRight = 2​
xlUp = 3​

--------------------
Set f = ShTest.Range("1:1").Find("CMA - ERP Variance", , xlValues, xlWhole, , , False)
When the Find method encounters the "CMA - ERP Variance" header, the result is stored in the 'f' object​

f.Offset(1).Resize(ShTest.Range("M" & Rows.Count).End(3).Row - 1)
So in object 'f' we have the cell where the header "CMA - ERP Variance" is located, with offset(1) we move one cell down.​
So we have to fill the column from the next cell to the header to the last row with data from the column to M, but we have to subtract 1, because the header is in row 1.​
--------------------

Perform the following test, so that you notice that the formulas are one row below the last row with data in column M:
VBA Code:
f.Offset(1).Resize(ShTest.Range("M" & Rows.Count).End(3).Row)

I hope it helps you.
😇
 
Upvote 0
Thank you Dante for this thorough explanation! It definitely helps!

On a side note, I would like to know with the current line of code that I have that will highlight any cell with a value other than zero to be yellow (color index 6) within the "Variance" column. If I correct the variance, and the value then becomes zero, is there a way to have the code automatically remove the yellow highlight? In other words, make it interactive somehow without requiring the user to have to manually remove the yellow highlight themselves?

Rich (BB code):
For Each ReconCel2 In .Cells
       If ReconCel2.Value <> 0 Then
                ReconCel2.Interior.ColorIndex = 6
       End If
Next
 
Upvote 0
If I correct the variance, and the value then becomes zero, is there a way to have the code automatically remove the yellow highlight? In other words, make it interactive somehow without requiring the user to have to manually remove the yellow highlight themselves?
I show you some options:

OPTION 1:
If you change the values, you can then run the next macro and it will adjust the colors of the entire column:​

Rich (BB code):
Sub Test_MatchReplace()
  Dim f As Range, c As Range
 
  Application.ScreenUpdating = False
 
  ' To find and replace certain original headers on test data report
    Set f = ShTest.Range("1:1").Find("Amount", , xlValues, xlWhole, , , False)
    If Not f Is Nothing Then f.Value = "CMA Amount"
    Set f = ShTest.Range("1:1").Find("Balance", , xlValues, xlWhole, , , False)
    If Not f Is Nothing Then f.Value = "CMA Balance"
 
  ' To create a formula for the "CMA - ERP Variance" column and highlight cell not equal to 0
    Set f = ShTest.Range("1:3").Find("CMA - ERP Variance", , xlValues, xlWhole, , , False)
    If Not f Is Nothing Then
      With f.Offset(1).Resize(ShTest.Range("M" & Rows.Count).End(3).Row - 3)
        .Formula = "=M2-N2"
        For Each c In .Cells
          If c.Value <> 0 Then
            c.Interior.ColorIndex = 6
          Else
            c.Interior.ColorIndex = xlNone
          End If
        Next
      End With
    End If

  Application.ScreenUpdating = True
End Sub
---------------------------------------------
OPTION 2:
Put a conditional format in the O column:​
varios 19oct2024.xlsm
EFGHIJKLMNO
1AcCMA Amountcma bmiltotservreb1reb2cma ierpCMA - ERP Variance
2Int17750456000172317230
3Int17760460000172417240
4Int17770476000172517250
5Int1778048400017261727-1
6Int17790494000172717270
7Int17800504000172817280
8Int17810514000172917209
9Int17820524000173017300
10Int17830534000173117310
11Int17840544000173217320
12Berk17850554000173317330
13Berk17860564000173417340
14Berk17870574000173517350
15
ShTest
Cell Formulas
RangeFormula
O2:O14O2=M2-N2
Cells with Conditional Formatting
CellConditionCell FormatStop If True
O2:O1000Cell Value<>0textNO


And you delete this part of the macro:
VBA Code:
        For Each c In .Cells
          If c.Value <> 0 Then
            c.Interior.ColorIndex = 6
          Else
            c.Interior.ColorIndex = xlNone
          End If
        Next

---------------------------------------------
OPTION 3:
If you modify any value in column M or N, automatically execute a code that reviews the values in column O and sets the color as appropriate:
Put the following code in events of your sheet:
VBA Code:
Private Sub Worksheet_Change(ByVal Target As Range)
  Dim rng As Range, c As Range, f As Range
 
  Set rng = Intersect(Target, Range("M2:N" & Rows.Count))
  If Not rng Is Nothing Then
    Set f = Range("1:1").Find("CMA - ERP Variance", , xlValues, xlWhole, , , False)
    If Not f Is Nothing Then
      For Each c In rng
        With Cells(c.Row, f.Column)
          If .Value <> 0 Then
            .Interior.ColorIndex = 6
          Else
            .Interior.ColorIndex = xlNone
          End If
        End With
      Next
    End If
  End If
End Sub
Note Sheet Event:
Right click the tab of the sheet you want this to work, select view code and paste the code into the window that opens up.​

And you delete this part of your macro:
VBA Code:
        For Each c In .Cells
          If c.Value <> 0 Then
            c.Interior.ColorIndex = 6
          Else
            c.Interior.ColorIndex = xlNone
          End If
        Next

---------------------------------------------

Option 4:
Delete your macro or you don't use it anymore.. No conditional formatting. Put the following code in your sheet events. Every time you modify a value in the M or N column, it will review the difference between the values you entered, that is, if you modify M5 = 100 and N5 = 98, then the macro automatically sets O5 = 2 and will turn it yellow.

VBA Code:
Private Sub Worksheet_Change(ByVal Target As Range)
  Dim rng As Range, c As Range, f As Range
 
  Set rng = Intersect(Target, Range("M2:N" & Rows.Count))
  If Not rng Is Nothing Then
    Set f = Range("1:1").Find("CMA - ERP Variance", , xlValues, xlWhole, , , False)
    If Not f Is Nothing Then
      For Each c In rng
        With Cells(c.Row, f.Column)
          .Value = Cells(c.Row, "M").Value - Cells(c.Row, "N").Value
          If .Value <> 0 Then
            .Interior.ColorIndex = 6
          Else
            .Interior.ColorIndex = xlNone
          End If
        End With
      Next
    End If
  End If
Note Sheet Event:
Right click the tab of the sheet you want this to work, select view code and paste the code into the window that opens up.​

To make it work, simply copy all the values in column n and paste them as values in the same column, the macro will update the entire column O.
From then on the macro will work for one change or for several changes in columns M or N.​

I hope some option works for you.
😅 😇
 
Upvote 0
Thank you Dante! These are all such great options! I will explore and see what works best for my scenario. I had no idea there was even such a thing as sheet event until your post!
I'm definitely learning new things everyday, so thank you again for all your help!
 
Upvote 0

Forum statistics

Threads
1,223,859
Messages
6,175,036
Members
452,606
Latest member
jkondrat14

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