【问题标题】:VBA - Error handling with multiple formsVBA - 多种形式的错误处理
【发布时间】:2014-11-04 12:53:06
【问题描述】:

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

问题的组成部分:

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

代码真的很简单,

模块错误

Public Sub raiseError()
  Call Err.Raise(2048, "errorSource", "errorDescription")
End Sub

主窗体

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。问题是caller 中的ErrorHandler 没有捕捉到错误!相反,raiseError 中引发的错误被视为未处理的错误!这意味着会出现一个丑陋的 messageBox 并将用户直接推入 VBEditor 中的代码 - 这是我想要避免的。

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

所以问题是

  1. 为什么会这样
  2. 如何解决这个问题,即如何捕获表单引发的错误,以免用户进入 VBEditor?

非常感谢任何帮助或解决方法。 丹尼尔

【问题讨论】:

  • 我认为您正在遭受this issue 的困扰。简短的回答是不要在 Class_Initalize() 事件过程中引发错误。
  • @RubberDuck:谢谢您的回复,但是,当我将按钮放在addClientForm 上并仅在此按钮的 _Click 事件中引发错误时,行为仍然相同 - 出现错误未处理。
  • @DanielBencik 在 [常规] 选项卡的 [错误处理] 部分中验证您的选项 - 确保选中“未处理错误中断”。

标签: forms vba


【解决方案1】:

我无法确定为什么会发生这种情况。我自己不能完全理解它,但有一些解决方法。您可以声明 ClientForm WithEvents 并通过侦听从 ClientForm 本身引发的自定义 OnError 事件来捕获错误。请注意,您不能对 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

主窗体

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

客户端表单

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

【讨论】:

  • 谢谢你。代码有效,对我来说是全新的东西,但正如你所说,我将重写我的代码以在每个表单中本地处理错误。
猜你喜欢
  • 2021-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-07
  • 2014-12-11
  • 2017-06-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多