Excel UDF 参数返回单元格引用而不是值
Excel UDF arguments returning cell references instead of values
这是我自 Excel 7.0 以来首次涉足用户定义函数。所以我很确定我犯了一个新手错误。
我在输入公式的单元格中遇到 #VALUE
错误。当我使用错误检查来显示计算步骤时,它将函数参数计算为单元格引用而不是值。
单元格中的公式:
=PavementNPV(P2, U2, T2, R2, Y2, Z2, AA2, I2, J2, K2, B2, W2, V2, X2)
错误检查 window 表示公式与所有单元格引用均带有下划线且 X2 为斜体。底部是下一次评估将导致错误的消息。错误是#VALUE。
单元格中的值:
- 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
代码:
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:$BF1,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
我最初定义了所有数据类型,但作为我的第一个故障排除步骤删除了它们。我最初还使用 Table 引用(例如 [@columnname])输入了公式。我希望能够 return 提高可读性。
如果您需要任何其他信息来提供帮助,请告诉我。提前谢谢你。
您 WorksheetFunction.VLookup
的参数 Arg2
不正确。它们不能是字符串。
使用
Application.WorksheetFunction.VLookup(Curve, Application.Range("Table4[#All]"), 2, False)
例如。
另一个错误可能是 WorksheetFunction.VLookup
returns #N/A
错误,因为无法在 table 数组中找到查找值。在这种情况下,函数会在此时中断,并且 returns #Value 也会中断。这可以避免在调用 WorksheetFunction.VLookup
之前使用 On Error Resume Next
并在它们之后使用 On Error GoTo 0
。
调试提示:打开 VBA 编辑器。在函数主体的某处设置断点。通过将函数作为公式输入到单元格中来调用该函数。代码在断点处停止。切换到 VBA 编辑器 window 并单步执行代码。
这是我自 Excel 7.0 以来首次涉足用户定义函数。所以我很确定我犯了一个新手错误。
我在输入公式的单元格中遇到 #VALUE
错误。当我使用错误检查来显示计算步骤时,它将函数参数计算为单元格引用而不是值。
单元格中的公式:
=PavementNPV(P2, U2, T2, R2, Y2, Z2, AA2, I2, J2, K2, B2, W2, V2, X2)
错误检查 window 表示公式与所有单元格引用均带有下划线且 X2 为斜体。底部是下一次评估将导致错误的消息。错误是#VALUE。
单元格中的值:
- 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
代码:
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:$BF1,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
我最初定义了所有数据类型,但作为我的第一个故障排除步骤删除了它们。我最初还使用 Table 引用(例如 [@columnname])输入了公式。我希望能够 return 提高可读性。
如果您需要任何其他信息来提供帮助,请告诉我。提前谢谢你。
您 WorksheetFunction.VLookup
的参数 Arg2
不正确。它们不能是字符串。
使用
Application.WorksheetFunction.VLookup(Curve, Application.Range("Table4[#All]"), 2, False)
例如。
另一个错误可能是 WorksheetFunction.VLookup
returns #N/A
错误,因为无法在 table 数组中找到查找值。在这种情况下,函数会在此时中断,并且 returns #Value 也会中断。这可以避免在调用 WorksheetFunction.VLookup
之前使用 On Error Resume Next
并在它们之后使用 On Error GoTo 0
。
调试提示:打开 VBA 编辑器。在函数主体的某处设置断点。通过将函数作为公式输入到单元格中来调用该函数。代码在断点处停止。切换到 VBA 编辑器 window 并单步执行代码。