Vba 您可以将要检查本地错误的代码委托给外部函数/子程序,这些函数/子程序位于调用堆栈中某个级别的顶部。因为它们在自己的范围内处理错误,所以它们不会相互混淆
考虑以下代码:Vba 您可以将要检查本地错误的代码委托给外部函数/子程序,这些函数/子程序位于调用堆栈中某个级别的顶部。因为它们在自己的范围内处理错误,所以它们不会相互混淆,vba,error-handling,Vba,Error Handling,考虑以下代码: Sub baseSub() Dim n As Integer n = checkDivision(1, 0) n = 1 / 0 ' cause an error End Sub Public Function checkDivision(iNumerator As Integer, iDenominator As Integer) On Error Resume Next checkDivision = iNume
Sub baseSub()
Dim n As Integer
n = checkDivision(1, 0)
n = 1 / 0 ' cause an error
End Sub
Public Function checkDivision(iNumerator As Integer, iDenominator As Integer)
On Error Resume Next
checkDivision = iNumerator / iDenominator
If Err.Number <> 0 Then
checkDivision = Err.Number
Exit Function
End If
End Function
Sub-baseSub()
作为整数的Dim n
n=检查除法(1,0)
n=1/0'导致错误
端接头
公共函数checkDivision(iNumerator为整数,iDenominator为整数)
出错时继续下一步
checkDivision=iNumerator/iDenominator
如果错误号为0,则
checkDivision=错误编号
退出功能
如果结束
端函数
相反:当从baseSub应用On Error Resume Next
时,位于调用堆栈顶部的所有函数也将忽略错误。但是,反过来就不行了
我想你可以利用这一点为自己谋利
总之,我相信你可以通过陷阱来解决这个问题
您放置在更高级别的委派职能中的预期错误
调用堆栈的一部分
如果这不起作用,那我就没主意了 这可能是你问题的一部分,但你在寻找什么样的解决方案?是否要缩短代码?或者您想构建一个可重用的库/函数集来处理ERORR吗?您会考虑使用外部库传递错误并从中获取一些信息吗?例如,拥有一个COM
errorhandler
类,并将错误号传递给它,然后返回一些内容。这只会缩短您的代码并为您提供一个可重用的错误处理程序,但我不确定这是否是您所寻求的解决方案类型。“万恶之源”是一个不合理的笼统陈述<代码>错误时继续下一步如果使用得当,则可以。事实上,给出了一个合法的示例(同样来自同一个源)。好的,因此您将控件发送到ARRAY\u ERROR\u HANDLER
,而不是本地处理错误。同样的区别。如果出现意外错误,如234
,或345
,或其他错误,该怎么办?您是否将这些错误处理程序从COMMON\u error\u HANDLER
复制粘贴到ARRAY\u error\u HANDLER
?重复的代码是错误的。(这就是为什么我希望重新显示错误,让常规错误处理程序像往常一样处理它。)@Jean-FrançoisCorbett:1:是的,错误恢复下一步肯定可以明智地使用。。。(世界上所有的枪都只用于自卫,对吗?)第二:阵法处理程序中怎么会出现234和345错误?如果是这样的话,这将不是一个数组错误。但是假设它们是由同一个处理程序引起的,那么它将由同一个处理程序处理,如果不是,我们可以将它重定向到不同的处理程序。我不确定你是否已经考虑清楚了。假设错误234
发生在错误转到数组\u error\u HANDLER的之后。控件传递给数组\u错误\u处理程序
,该处理程序不知道如何处理它。处理234
的代码位于COMMON\u ERROR\u HANDLER
中。这是我的难题。用枪来比喻,我不明白。我很欣赏你的观点,但有时要抓住错误()。这就是我的问题,当然没问题。问题中的示例代码并没有真正建议您共享的例外示例——它们似乎建议使用错误处理程序作为反模式来解决常见问题(在数组中查找-两个同名的人)——所以我感到困惑。如果我对这个问题理解正确,尽管我不确定,但我会尝试制定一个更好的答案,直接在较低的层次上解决错误处理问题。再想一想,也许我的问题是反模式。我不确定。恩,赏金一定要给某人,你的回答让我想得最多,所以你去吧!谢谢@JF。我希望这会有帮助。
Public Sub sixsixsixBytes()
On Error GoTo COMMON_ERROR_HANDLER
'Some code...
On Error GoTo ARRAY_ERROR_HANDLER
Call Err.Raise(123) 'lets say error occured in personIndex = ....
'it will jump to 2nd error handler and come back
'some code again...
'If statement is not required at all
Call Err.Raise(666)
On Error GoTo COMMON_ERROR_HANDLER:
'some code again...
Call Err.Raise(234)
Exit Sub
'# MULTIPLE ERROR HANDLERS
COMMON_ERROR_HANDLER:
Select Case Err.Number
Case 234: MsgBox 234
Case 345: MsgBox 345
End Select
ARRAY_ERROR_HANDLER:
Select Case Err.Number
Case 123:
MsgBox "Name not found in person array. Using default person."
Resume Next 'or Resume after changing a value (as per your need)
Case 666:
MsgBox "Some other error"
Resume Next
End Select
End Sub
On Error Resume Next
personIndex = FindInArray(personName, personArray)
If Err.Number = ERR__ELEMENT_NOT_FOUND_IN_ARRAY Then
MsgBox "Name not found in person array. Using default person."
Else
End If
If Not (in_array(vArray, "Jean-Francois")) Then
MsgBox "Name not found in person array. Using default person."
End If
Public Function in_array(vArray As Variant, sItem As String) As Boolean
Dim lCnt As Long
in_array = False
Do Until lCnt = UBound(vArray) + 1
If StrComp(vArray(lCnt), sItem, CompareMethod.Text) = 0 Then
in_array = True
Exit Function
End If
lCnt = lCnt + 1
Loop
End Function
personIndex = FindInArray(personName, personArray)
Sub baseSub()
Dim n As Integer
n = checkDivision(1, 0)
n = 1 / 0 ' cause an error
End Sub
Public Function checkDivision(iNumerator As Integer, iDenominator As Integer)
On Error Resume Next
checkDivision = iNumerator / iDenominator
If Err.Number <> 0 Then
checkDivision = Err.Number
Exit Function
End If
End Function