简体   繁体   中英

Excel UDF arguments returning cell references instead of values

This is my first foray into user defined functions since Excel 7.0. So I'm pretty sure I'm making a newbie error.

I'm getting a #VALUE error in the cell where I've entered the formula. When I use Error Checking to Show Calculation Steps, it evaluates the functions arguments as the cell references rather than values.

The formula in the cell:

=PavementNPV(P2, U2, T2, R2, Y2, Z2, AA2, I2, J2, K2, B2, W2, V2, X2)

Error checking window says the formula exactly with all cell references underline and X2 italicized. At the bottom is the message that the next evaluation will cause an error. The error is #VALUE.

The values in the cells:

  • P2 = 10
  • U2 = 63.17986
  • T2 = 10
  • R2 = 3
  • Y2 = $0.28
  • Z2 = $1.32
  • AA2 = $2.58
  • I2 = 14000
  • J2 = 45
  • K2 = 60
  • B2 = 292
  • W2 = 73.17986
  • V2 = 8
  • X2 = 0.05

The code:

Function PavementNPV(AssumedLife, PvmtCondition, AgeByCondition, Curve, CarVOC As Currency, BusVOC As Currency, TruckVOC As Currency, AvgDailyTraffic, TruckCount, BusCount, SegLength, RestPCTGain, RestAgeByCondition, Rate) As Currency

'Calculate Yr1 restored PCI(PvmtCondition - Pavement Condition Index) value
'   =PvmtCondition + Assumed Life
Dim Yr1RestPCI
Yr1RestPCI = PvmtCondition + AssumedLife

'For each year of Assumed life, calculate doNothingTotalAnnualVOCIncreaseRange and restoredTotalAnnualVOCIncreaseRange:
'   =365*(CarVOCIncrease% as (Application.WorksheetFunction.VLOOKUP((PCIofYr as (If Yr1 then PvmtCondition, else 100*(1/(1+EXP((AgeByCondition+year(e.g. 2)-1)/Application.WorksheetFunction.VLOOKUP(Curve,Table4[#All],2,FALSE)-Application.WorksheetFunction.VLOOKUP(Curve,Table4[#All],3,FALSE))))*Application.WorksheetFunction.VLOOKUP(Curve,Table4[#All],4,FALSE)))),'User Cost'!$BC$5:$BF$151,2))*CarVOC*AvgDailyTraffic+BusVOCIncrease%*BusVOC+TruckVOCIncrease%*TruckVOC)*SegLength/5280)
Dim arydoNothingPCI()
ReDim arydoNothingPCI(1 To AssumedLife)
Dim aryRestoredPCI()
ReDim aryRestoredPCI(1 To AssumedLife)
Dim arydoNothingVOCIncrease() As Currency
ReDim arydoNothingVOCIncrease(1 To AssumedLife)
Dim aryRestoredVOCIncrease() As Currency
ReDim aryRestoredVOCIncrease(1 To AssumedLife)
Dim i

arydoNothingPCI(1) = PvmtCondition
aryRestoredPCI(1) = Yr1RestPCI

For i = 2 To AssumedLife
    arydoNothingPCI(i) = 100 * (1 / (1 + Application.WorksheetFunction.Exp((AgeByCondition + i) - 1) / Application.WorksheetFunction.VLookup(Curve, "Table4[#All]", 2, False) - Application.WorksheetFunction.VLookup(Curve, "Table4[#All]", 3, False))) * Application.WorksheetFunction.VLookup(Curve, "Table4[#All]", 4, False)
    aryRestoredPCI(i) = 100 * (1 / (1 + Application.WorksheetFunction.Exp((RestAgeByCondition + i) - 1) / Application.WorksheetFunction.VLookup(Curve, "Table4[#All]", 2, False) - Application.WorksheetFunction.VLookup(Curve, "Table4[#All]", 3, False))) * Application.WorksheetFunction.VLookup(Curve, "Table4[#All]", 4, False)
Next
'Testing function so far by asking it to return something simple
PavementNPV = CarVOC


'Calculate Total PV Benefits by calculating NPV of doNothing minus NPV or restored
'   =Application.WorksheetFunction.NPV(rate,doNothingTotalAnnualVOCIncreaseRange)- Application.WorksheetFunction.NPV(rate,restoredTotalAnnualVOCIncreaseRange)
'   or for each NPV =(Yr1VOCIncrease/(1+rate)^1)+(Yr2VOCIncrease/(1+rate)^2)+(Yr3VOCIncrease/(1+rate)^3) etc for all years


End Function

I originally had all of the data types defined, but removed those as my first troubleshooting step. I also originally had the formula entered using Table references (eg [@columnname]). I would love to be able to return to that for readability.

Please let me know if you need any additional information to help. Thank you in advance.

Your parameters Arg2 of WorksheetFunction.VLookup are not correct. They can't be strings.

Use

Application.WorksheetFunction.VLookup(Curve, Application.Range("Table4[#All]"), 2, False)

for example.

Another error could be that the WorksheetFunction.VLookup returns the #N/A error because the lookup value could not be found within the table array. In this case the function breaks at this point and returns #Value also. This you could avoid using On Error Resume Next before the calls of WorksheetFunction.VLookup and On Error GoTo 0 after them.

Hint to debug: Have the VBA Editor open. Set a breakpoint somewhere in the function's body. Call the function by input it as formula in a cell. The code stops at the breakpoint. Change to the VBA Editor window and step through the code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM