I have a the following on my worksheet:
A1
]RANGE
, and scoped to the worksheet]A1
and RANGE
I then have a VBA function called Calculate
, as follows:
Function Calculate(LookupValue As Double, LookupRange As Range) As Double
Calculate = [VLOOKUP(LookupValue, LookupRange, 2)]
End Function
The cell that determines the percentage has the following:
=Calculate(A1, RANGE)
Problem is that the cell just returns #VALUE!
...
Any idea what I could be doing wrong?
I have tried several things like type-hinting to Range()
, passing LookupRange.Value2
to VLOOKUP
, etc, none of which worked.
I have also tried to debug, noting that LookupRange
does actually contain the range required in Value2
, which is is why I tried to pass it to the function.
Side Note: The function and layout mentioned above is just a dummy - the actual function is somewhat more complex as it relies on negotiated rates, monthly margins, etc. This is why I'm using VBA in the first place. I know that I'm doing something wrong with the lookup, as it is the only thing that seems to be failing within the function - everything else corresponds and calculates.
From MSDN:
The advantage of using square brackets is that the code is shorter. The advantage of using
Evaluate
is that the argument is a string, so you can either construct the string in your code or use a Visual Basic variable.
in other words you can use
Calculate = [VLOOKUP(3, A1:B100, 2)]
but you can not use
LookupValue = 3
LookupRange = Range("A1:B100")
'or
'LookupRange = "A1:B100"
Calculate = [VLOOKUP(LookupValue, LookupRange, 2)]
What you can do is:
Option 1:
Function Calculate(LookupValue As Double, LookupRange As Range) As Double
Calculate = Evaluate("VLOOKUP(" & LookupValue & "," & LookupRange.Address & ", 2")
End Function
or better:
Function Calculate(LookupValue As Double, LookupRange As Range) As Double
Calculate = Evaluate("VLOOKUP(" & LookupValue & ",'" & _
LookupRange.Parent.Name & "'!" & LookupRange.Address & ", 2")
End Function
However I suggest:
Option 2:
Function Calculate(LookupValue As Double, LookupRange As Range) As Double
Calculate = Application.VLookup(LookupValue, LookupRange, 2)
End Function
I hope you know about meaning of 4th parameter:
If
TRUE
or omitted, an exact or approximate match is returned. If an exact match is not found, the next largest value that is less than lookup_value is returned. The values in the first column of table_array must be placed in ascending sort order; otherwise,VLOOKUP
may not give the correct value. You can put the values in ascending order by choosing the Sort command from the Data menu and selecting Ascending.
Btw, Calculate
is not good name for UDF, since VBA already has function Application.Calculate
. I'd rename it to avoid confusion.