Home » excel » excel – Alternative to MATCH function on horizontal data

excel – Alternative to MATCH function on horizontal data

Posted by: admin May 14, 2020 Leave a comment

Questions:

This function is supposed to compute take the number “days”, express it in terms of “years”, and find an approximate match in the worksheet.

Then it takes the value of the cell below this approximate match and adds the “shift” to its value. This is what a part of my data look like.

This is how my data in Excel look like

Here is my code

Public Function Bucket(range As range, years As Long, shift As Long)
    days = years * 365
    approx_days = Application.WorksheetFunction.Index(range, Application.WorksheetFunction.Match(days, range, 1))
    rate_approx_days = Application.WorksheetFunction.Index(range, Application.WorksheetFunction.Match(days, range, 1) + 1)
    Bucket = rate_approx_days + shift
End Function


Sub try()
    With Worksheets("Sheet1")
        Debug.Print (Bucket(.range("A14:AX14"), 1, 1))
    End With
End Sub

If it worked, the number 0.99636 (-0.00364+1) should appear in the immediate window, but I get 370.

Is there any alternative that I could use on horizontal data so that it worked correctly or any way I could modify the function?

How to&Answers:
  1. Don’t use Range as a variable name it is a reserved word.
  2. Index() returns a range
  3. use Offset to move from your indexed approx_days one row down
  4. Use Option Explicit and declare all your variables

Option Explicit

Public Function Bucket(ByVal Rng As Range, ByVal Years As Long, ByVal Shift As Long) As Double
    Dim Days As Long
    Days = Years * 365

    Dim approx_days As Range
    Set approx_days = Application.WorksheetFunction.Index(Rng, Application.WorksheetFunction.Match(Days, Rng, 1))

    Dim rate_approx_days As Range
    Set rate_approx_days = approx_days.Offset(1, 0)

    Bucket = rate_approx_days + Shift
End Function


Sub try()
    With Worksheets("Sheet1")
        Debug.Print Bucket(.Range("A14:AX14"), 1, 1)
    End With
End Sub

I recommend to implement some error handler and return an error value if something with Match/Index goes wrong.

Option Explicit

Public Function Bucket(ByVal Rng As Range, ByVal Years As Long, ByVal Shift As Long) As Variant
    On Error GoTo ERR_HANDLING 'if something goes wrong return error value
    Dim Days As Long
    Days = Years * 365

    Dim approx_days As Range
    Set approx_days = Application.WorksheetFunction.Index(Rng, Application.WorksheetFunction.Match(Days, Rng, 1))

    Dim rate_approx_days As Range
    Set rate_approx_days = approx_days.Offset(1, 0)

    Bucket = rate_approx_days + Shift

    On Error GoTo 0

    Exit Function
ERR_HANDLING:
    Bucket = CVErr(xlErrNA) 'return N/A error
    Err.Clear
End Function


Sub try()
    With Worksheets("Sheet1")
        Dim Result As Variant
        Result = Bucket(.Range("A14:AX14"), 1, 1)

        If IsError(Result) Then
            Debug.Print "Error occured"
        Else
            Debug.Print Result
        End If
    End With
End Sub

Note that the Bucket function now returns a Variant/Double or in case of error a Variant/Error. Therefore the function is declared as Variant now.