我的应用程序有几种相互调用的形式。我遇到了错误处理问题,由于项目太大而无法发布,我创建了仍然重现问题的代码的最小子集。该文件可以找到here
问题的组成部分:
raiseError
- 一个只会引发错误的函数mainForm
- 一个带有一个按钮的表单 - 点击后会打开addClientForm
addClientForm
- 通过raiseError
showMainForm
- 显示mainForm
代码非常简单,
模块错误
Public Sub raiseError()
Call Err.Raise(2048, "errorSource", "errorDescription")
End Sub
的MainForm
Private Sub cbAddClientForm_Click()
Dim xAddClientForm As New addClientForm: Call xAddClientForm.Show
End Sub
AddClientForm
Private Sub UserForm_Initialize()
Call raiseError
End Sub
呼叫者
Public Sub caller()
On Error GoTo ErrorHandler
Dim xMainForm As New mainForm: Call xMainForm.Show
ErrorExit:
Exit Sub
ErrorHandler:
Call MsgBox("Error appeared", vbOKOnly)
On Error Resume Next
GoTo ErrorExit
End Sub
caller
显示mainForm
,一旦用户点击该按钮,系统会初始化addClientForm
,从而调用raiseError
。问题是ErrorHandler
中的caller
没有发现错误!相反,raiseError
中引发的错误被视为未处理的错误!这意味着一个丑陋的messageBox出现并将用户直接推入VBEditor中的代码 - 这就是我想要避免的。
我摆弄了这个问题的各种设置,只要没有一个表单调用另一个表单,错误处理按预期工作。在附件中,所有调查都与测试假设一起写入不同的模块。
所以问题是
非常感谢任何帮助或解决方法。 丹尼尔
答案 0 :(得分:2)
我无法肯定地说为什么这种情况正在发生。我自己也不能理解它,但是有一些工作要做。您可以声明ClientForm
WithEvents并通过侦听从OnError
内部引发的自定义ClientForm
事件来捕获错误。请注意,您无法为MainForm
执行此操作,因为您无法在模块内声明变量WithEvents
。它必须是一个班级。
这里的重大缺陷是您需要手动将客户端表单中的错误重定向到它的OnError
事件,然后为您希望处理错误的每个客户端表单创建一个事件过程。另一个垮台是you can't "hear" events raised in the Class_Intialize
event procedure.
所以,总而言之,您可能需要考虑在客户端表单中本地处理任何错误。
<强>模块1 强>
Public Sub caller()
Dim xMainForm As New MainForm
xMainForm.Show
End Sub
<强>的MainForm 强>
Option Explicit
Private WithEvents xClientForm As ClientForm
Private Sub cbAddClientForm_Click()
Set xClientForm = New ClientForm
xClientForm.Show
End Sub
Private Sub xClientForm_OnError(Err As ErrObject)
MsgBox Err.Number & ": " & Err.Description & vbNewLine & Err.Source & " raised an error.", vbCritical, "Error"
End Sub
<强> ClientForm 强>
Option Explicit
Public Event OnError(Err As ErrObject)
Private Sub UserForm_Click()
On Error GoTo ErrHandler:
raiseError
Exit Sub
ErrHandler:
RaiseEvent OnError(Err)
End Sub
Private Sub UserForm_Initialize()
' can't raise events from initialize, they won't be "heard"
' https://stackoverflow.com/q/26589039/3198973
End Sub
Public Sub raiseError()
Err.Raise 2048, TypeName(Me), "errorDescription"
End Sub