使用用户定义函数 (VBA) 引发错误
Posted
技术标签:
【中文标题】使用用户定义函数 (VBA) 引发错误【英文标题】:Raising errors with User Defined Functions (VBA) 【发布时间】:2021-01-13 03:07:46 【问题描述】:我在 vba 中创建了一个用户定义的函数来根据先进先出库存系统计算利润。在转到实际代码之前,我想检查一下天气输入是否有效。
'---------------Check Information for errors----------------------
SellSum = Application.WorksheetFunction.Sum(SellQuantity)
BuySum = Application.WorksheetFunction.Sum(BuyQuantity)
SellPCount = Application.WorksheetFunction.Count(SellPrice)
SellQCount = Application.WorksheetFunction.Count(SellQuantity)
BuyPCount = Application.WorksheetFunction.Count(BuyPrice)
BuyQCount = Application.WorksheetFunction.Count(BuyQuantity)
If SellSum > BuySum Then 'More sales than inventory, throw error
FIFO_PROFIT = VBA.CVErr(XlCVError.xlErrValue)
End If
If (BuyPCount <> BuyQCount Or SellPCount <> SellQCount) Then 'Incomplete data, throw error
FIFO_PROFIT = VBA.CVErr(XlCVError.xlErrValue)
End If
'-----------------------------------------------------------------
而在真正的代码之后,我就有了最终的价值,
FIFO_PROFIT = RunningProfit
但是,当我输入无效数据时,应该会引发错误,但它什么也没做。就像它只是跳过错误检查并跳转到实际代码。
实际代码有点长,我不相信它与它有任何关系。但如果有人想评论它, https://pastebin.com/fA2pY52f
【问题讨论】:
是我还是你最后覆盖了 FIFO_PROFIT 值?如果您覆盖它,它不会作为错误出现,对吗?在这种情况下,只需在每个 If 语句中添加一个GoTo
来检查错误并将代码改写到函数的末尾。
@EvilBlueMonkey,是的,你是对的,我正在覆盖,因为我认为这是唯一可行的方法。让我检查您的解决方案,如果它有效与否,请与您联系。 +1 快速响应
@EvilBlueMonkey,这将如何运作? if(condition) goto End Function ????
rtfm ,当光标在你不知道的方法上时按 F1 键访问(CVErr),但你可以Raise 一个真正的错误!并使用Option Explicit!
【参考方案1】:
我想说这样的事情可能会奏效:
Function FIFO_PROFIT(SellPrice As Variant, SellQuantity As Variant, BuyPrice As Variant, BuyQuantity As Variant) As Variant
'Calculate the Profit according to the FIFO method
'---------------Check Information for errors----------------------
SellSum = Application.WorksheetFunction.Sum(SellQuantity)
BuySum = Application.WorksheetFunction.Sum(BuyQuantity)
SellPCount = Application.WorksheetFunction.Count(SellPrice)
SellQCount = Application.WorksheetFunction.Count(SellQuantity)
BuyPCount = Application.WorksheetFunction.Count(BuyPrice)
BuyQCount = Application.WorksheetFunction.Count(BuyQuantity)
If SellSum > BuySum Then 'More sales than inventory, throw error
FIFO_PROFIT = VBA.CVErr(XlCVError.xlErrValue)
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
GoTo FIFO_PROFIT_IS_ERROR '<--------------------ADDED CODE (1 of 3)X
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
End If
If (BuyPCount <> BuyQCount Or SellPCount <> SellQCount) Then 'Incomplete data, throw error
FIFO_PROFIT = VBA.CVErr(XlCVError.xlErrValue)
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
GoTo FIFO_PROFIT_IS_ERROR '<--------------------ADDED CODE (2 of 3)X
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
End If
'-----------------------------------------------------------------
'--------------MoreVariables--------------------------------------
Dim RunningSale As Variant
Dim RunningBuy As Variant
Dim RunningCost As Variant
Dim RunningBuyQuantity As Variant
Dim RunningSales As Variant
Dim RunningProfit As Variant
Dim Residual As Variant
Dim UsedupResidual As Variant
Dim y As Variant
y = 1
RunningCost = 0
Residual = 0
UsedupResidual = 0
RunningSales = 0
RunningProfit = 0
'-----------------------------------------------------------------
For x = 1 To SellQCount
If y <> 1 Then 'BUGtest
RunningBuyQuantity = Residual + BuyQuantity(y).Value2
End If
While (RunningBuyQuantity <= SellQuantity(x).Value2 And y <= BuyQCount) 'Bugtest
If y = 1 Then
RunningCost = RunningCost + (BuyPrice(y).Value2 * BuyQuantity(y).Value2)
Else
RunningCost = RunningCost + ((BuyPrice(y).Value2 * BuyQuantity(y).Value2) + (BuyPrice(y - 1).Value2 * Residual))
End If
Residual = 0
RunningBuyQuantity = RunningBuyQuantity + BuyQuantity(y).Value2
y = y + 1
Wend
If RunningBuyQuantity > SellQuantity(x).Value2 Then
Residual = SellQuantity(x).Value2 - RunningBuyQuantity
UsedupResidual = BuyQuantity(y).Value2 - Residual
RunningCost = RunningCost + (UsedupResidual * BuyPrice(y).Value2)
End If
RunningSales = SellPrice(x).Value2 * SellQuantity(x).Value2
RunningProfit = RunningProfit + RunningSales - RunningCost
RunningSales = 0
RunningCost = 0
Next x
FIFO_PROFIT = RunningProfit
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
FIFO_PROFIT_IS_ERROR: '<--------------------ADDED CODE (3 of 3) X
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
End Function
我已经使用了你的整个函数并添加了 3 行代码。我没有检查代码本身,所以没有对其进行评估。在这两种情况下(更多的销售和不完整的数据),FIFO_PROFIT 已正确设置,然后GoTo
指令将代码发送到 FIFO_PROFIT_IS_ERROR 行,方便地放置在函数的末尾。有关GoTo
指令here 的更多信息。
再一次,您也可以使用Exit Function
指令。它不需要第三行 FIFO_PROFIT_IS_ERROR,它也可以工作。这将导致:
Function FIFO_PROFIT(SellPrice As Variant, SellQuantity As Variant, BuyPrice As Variant, BuyQuantity As Variant) As Variant
'Calculate the Profit according to the FIFO method
'---------------Check Information for errors----------------------
SellSum = Application.WorksheetFunction.Sum(SellQuantity)
BuySum = Application.WorksheetFunction.Sum(BuyQuantity)
SellPCount = Application.WorksheetFunction.Count(SellPrice)
SellQCount = Application.WorksheetFunction.Count(SellQuantity)
BuyPCount = Application.WorksheetFunction.Count(BuyPrice)
BuyQCount = Application.WorksheetFunction.Count(BuyQuantity)
If SellSum > BuySum Then 'More sales than inventory, throw error
FIFO_PROFIT = VBA.CVErr(XlCVError.xlErrValue)
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Exit Function '<--------------------ADDED CODE (1 of 2)X
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
End If
If (BuyPCount <> BuyQCount Or SellPCount <> SellQCount) Then 'Incomplete data, throw error
FIFO_PROFIT = VBA.CVErr(XlCVError.xlErrValue)
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Exit Function '<--------------------ADDED CODE (1 of 2)X
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
End If
'-----------------------------------------------------------------
'--------------MoreVariables--------------------------------------
Dim RunningSale As Variant
Dim RunningBuy As Variant
Dim RunningCost As Variant
Dim RunningBuyQuantity As Variant
Dim RunningSales As Variant
Dim RunningProfit As Variant
Dim Residual As Variant
Dim UsedupResidual As Variant
Dim y As Variant
y = 1
RunningCost = 0
Residual = 0
UsedupResidual = 0
RunningSales = 0
RunningProfit = 0
'-----------------------------------------------------------------
For x = 1 To SellQCount
If y <> 1 Then 'BUGtest
RunningBuyQuantity = Residual + BuyQuantity(y).Value2
End If
While (RunningBuyQuantity <= SellQuantity(x).Value2 And y <= BuyQCount) 'Bugtest
If y = 1 Then
RunningCost = RunningCost + (BuyPrice(y).Value2 * BuyQuantity(y).Value2)
Else
RunningCost = RunningCost + ((BuyPrice(y).Value2 * BuyQuantity(y).Value2) + (BuyPrice(y - 1).Value2 * Residual))
End If
Residual = 0
RunningBuyQuantity = RunningBuyQuantity + BuyQuantity(y).Value2
y = y + 1
Wend
If RunningBuyQuantity > SellQuantity(x).Value2 Then
Residual = SellQuantity(x).Value2 - RunningBuyQuantity
UsedupResidual = BuyQuantity(y).Value2 - Residual
RunningCost = RunningCost + (UsedupResidual * BuyPrice(y).Value2)
End If
RunningSales = SellPrice(x).Value2 * SellQuantity(x).Value2
RunningProfit = RunningProfit + RunningSales - RunningCost
RunningSales = 0
RunningCost = 0
Next x
FIFO_PROFIT = RunningProfit
End Function
【讨论】:
以上是关于使用用户定义函数 (VBA) 引发错误的主要内容,如果未能解决你的问题,请参考以下文章
用户定义的函数在 vba 中工作正常,而从显示“值”错误的 excel 表调用时
尝试调用外部 VBA 函数时,只能强制在公共对象模块中定义的用户定义类型