excelexcel-formulaexcel-udfvba

Create UDF that works when dragged down


I think I'm overlooking something simple...

My idea is to create a function in Excel that's easier to set up than the following: =INDEX($A$1:$A$5,AGGREGATE(15,6,ROW($B$1:$B$5)/($B$1:$B$5=1),ROW(1:1)))
(see ScottCraner's comment in this answer for that function in practice)

I have created the following UDF:

Public Function findUnique(ByVal indexRange As Range, matchRange As Range, matchVal As Long)
' Trying to create a dynamic function of:
' =INDEX($A$1:$A$5,AGGREGATE(15,6,ROW($B$1:$B$5)/($B$1:$B$5=1),ROW(1:1)))

 findUnique = Evaluate("=Index(" & indexRange.Address & ",AGGREGATE(15,6,Row(" & matchRange.Address & _
    ")/(" & matchRange.Address & "=" & matchVal & "),Row(" & ActiveCell.Row & ":" & ActiveCell.Row & ")))")

End Function

And it almost works. Except, when I drag down from the first row, the data doesn't update. I have to click into the cell to "retrigger" the function to get the correct data to show:

enter image description here

(Column D is that formula, entered correctly).

But, how do I get the formula to update automatically, without re-entering the cell?

I've also tried adding a fourth Variable:

Public Function findUnique(ByVal indexRange As Range, matchRange As Range, matchVal As Long, curRow as Long)

findUnique = Evaluate("=Index(" & indexRange.address & ",AGGREGATE(15,6,Row(" & matchRange.address & _
    ")/(" & matchRange.address & "=" & matchVal & "),Row(" & curRow & ":" & curRow & ")))")

End Function

and enter like: =findUnique($A$1:$A$5,$B$1:$B$5,1,ROW()) but it just returns a #VALUE error

(Also, how do I avoid ActiveCell.Row, as I have it drilled in to my head to avoid using Active anything...)

Thanks for any thoughts or advice!


Solution

  • From this SO answer, try the following ...

     With Application.Caller
        CallerRow = .Row
     End With
     findUnique = Evaluate("=Index(" & indexRange.Address & ",AGGREGATE(15,6,Row(" & matchRange.Address & _
        ")/(" & matchRange.Address & "=" & matchVal & "),Row(" & CallerRow & ":" & CallerRow & ")))")