我想知道是否存在预先构建的系统函数,该函数将取消当前正在触发的事件的整个内存堆栈,而不必退出Microsoft Access VBA中的堆栈跟踪中的每个过程?
我正在寻找以下内容:
Public Sub Procedure2()
CancelEvent 'This would return from procedure2, proedure1, and the specific event Sub
End Sub
Public Sub Procedure1()
Procedure2
End Sub
Private Sub SomeControl_SomeEvent()
Procedure1
End Sub
我已经尝试过DoCmd.CancelEvent,但程序执行后仍然继续,并且不取消整个过程堆栈(我可能一直在寻找错误的系统Sub)。我能想到实现这个目的的唯一方法(没有讨厌的If-Else语句来检查下面的堆栈过程是否必须继续,如果我退出上面的堆栈过程)是使用异常,并具有如下内容:< / p>
Public Sub Procedure2()
Err.Raise 1 'Just an example exception
End Sub
Public Sub Procedure1()
Procedure2
End Sub
Private Sub SomeControl_SomeEvent()
On Error Goto HandleError
Goto StartSub
HandleError:
Exit Sub
StartSub:
Procedure1
End Sub
或者,是否可以仅在VBA中捕获特定的异常,因为我可能只需要在最低的堆栈过程中捕获此异常?
答案 0 :(得分:4)
必须将其作为错误处理策略实施。
我定义了一个公共枚举来正式跟踪(并命名)自定义错误代码,从vbObjectError
+某个值开始:
Public Enum CustomError
CE_Cancelled = vbObjectError + 42
CE_SomeOtherCustomError
'...
End Enum
然后当你想“取消”一个事件并“走上调用堆栈”时,你可以提出那个错误:
Public Sub RaiseOperationCancelledError(ByVal source As String)
Err.Raise CE_Cancelled, source, "Operation was cancelled."
End Sub
RaiseOperationCancelledError
运行时究竟会发生什么,完全取决于此时调用堆栈中的On Error
语句。
假设您在调用堆栈的顶部(实际上是erm, bottom )有一些控制事件:
Private Sub SomeControl_SomeEvent()
On Error Goto CleanFail
DoSomething
CleanExit:
Exit Sub
CleanFail:
If Err.Number = CE_Cancelled Then
MsgBox Err.Description '"Operation was cancelled."
Else
Err.Raise Err.Number 'we don't know what happened; rethrow.
End If
Resume CleanExit
End Sub
如果DoSomething
有,IDK,说文件I / O,需要处理错误:
Sub DoSomething()
On Error GoTo CleanFail
Dim fileNumber As Long
fileNumber = FreeFile
'do stuff
'...
CleanExit:
Close fileNumber
Exit Sub
CleanFail:
If Err.Number = 53 Then
' handle "file not found" error
Resume CleanExit
Else If Err.Number = CE_Cancelled Then
Close fileNumber ' we won't run CleanExit if we rethrow!
Err.Raise Err.Number ' rethrow
End If
End Sub
现在,这几乎和它一样邋..那有什么问题?
问题是你正在为流量控制使用自定义运行时错误,并且不可避免地会变成任何语言的意大利面条代码,无论是否有例外。
如果您正在做某事并且用户取消了它,那么您将拥有一个返回一个值的函数,该值可以准确地告诉您 - 例如用户取消了文件浏览器对话框,我们无法继续导出 - 您不会引发自定义错误!相反,你创建了一个函数,它的职责是返回用户选择的文件,使用一些机制告诉它的调用者毕竟不会有一个导出目标 - 该函数可能返回一个空字符串而不是一个有效的文件路径;然后调用者知道如果返回的字符串为空,则需要挽救并返回其自己的调用者,自然地解除调用堆栈 。