VBA - 使用多个表单进行错误处理

时间:2014-11-04 12:53:06

标签: forms vba

我的应用程序有几种相互调用的形式。我遇到了错误处理问题,由于项目太大而无法发布,我创建了仍然重现问题的代码的最小子集。该文件可以找到here

问题的组成部分:

  1. raiseError - 一个只会引发错误的函数
  2. mainForm - 一个带有一个按钮的表单 - 点击后会打开addClientForm
  3. addClientForm - 通过raiseError
  4. 引发错误的表单
  5. showMainForm - 显示mainForm
  6. 的来电者

    代码非常简单,

    模块错误

    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中的代码 - 这就是我想要避免的。

    我摆弄了这个问题的各种设置,只要没有一个表单调用另一个表单,错误处理按预期工作。在附件中,所有调查都与测试假设一起写入不同的模块。

    所以问题是

    1. 为什么会这样?
    2. 如何解决这个问题,即如何捕获表单引发的错误,以免用户被抛入VBEditor?
    3. 非常感谢任何帮助或解决方法。 丹尼尔

1 个答案:

答案 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
相关问题