【问题标题】:How to pass error in VBA userform to calling method如何将 VBA 用户窗体中的错误传递给调用方法
【发布时间】:2013-05-31 09:23:45
【问题描述】:

VBA 用户窗体中的错误,除了那些在初始化事件中发生的错误,似乎不会冒泡到调用方法。有什么方法可以强制错误冒泡吗?

VBA 用户表单包含一个名为 userform_error 的事件,定义为

Private Sub UserForm_Error(
    ByVal Number As Integer, 
    ByVal Description As MSForms.ReturnString, 
    ByVal SCode As Long, 
    ByVal Source As String, 
    ByVal HelpFile As String, 
    ByVal HelpContext As Long, 
    ByVal CancelDisplay As MSForms.ReturnBoolean
)

当用户表单中发生错误时调用事件 UserForm_Error 似乎是合乎逻辑的,但情况似乎并非如此。事实上,我找不到任何关于 Userform_Error 的文档。

我已经搜索了 MSDN、Bing、Google、StackOverflow、DuckDuckGo,但我找不到一个好的方法,或者任何关于 UserForm_error 实际作用的文档。

【问题讨论】:

  • Excel VBA?访问 VBA?你能用代码举例说明你想做什么吗?
  • 我认为这是不可能的。您有多少事件不想编写错误处理程序?
  • 按钮点击时调用了多少这样的外部函数/方法?你可以做的是编写方法来包装这些外部 DLL 函数,捕获错误以进行日志记录。
  • 只有在 VBA 编辑器不可用时才会调用错误事件,例如在 Access 中,如果您创建 MDE 并强制出错,例如在 Button_Click-Event 中将 1 除以 0,则错误事件将启动并捕获错误,但是如果您在普通 MDB 文件中引发错误,则如果错误照常发生,VBA-Editor 将保持在线状态。
  • 根据帮助文件,只有当控件无法处理错误时才会引发此事件。您可以通过打开对象浏览器 -> 下拉列表中的“MSForms” -> 在类列表中选择“用户窗体”,然后右键单击“错误”事件来查看帮助文件

标签: vba userform


【解决方案1】:

很难为您提供准确的信息,该组件是古老的。只是一些背景。

UserForm 对象由 Microsoft Forms 2.0(一个 ActiveX 组件库)实现。它是一个用于向任何应用程序添加表单的通用库,它不仅限于 Office 应用程序。您可以在计算机上的 c:\windows\syswow64\fm20.dll 中找到它(system32 用于 32 位计算机)。该组件的文档曾经由 fm20.chm 提供。 Microsoft 不再提供此帮助文件,您仍然可以通过 google 查询找到它。然而,大多数提供它的网站看起来非常阴暗。 This one 看起来最不粘。其实查看这个文件挺麻烦的,我可以浏览目录但是没有页面显示文字了。

我发现的一种解决方法是使用 HTML Workshop 实用程序反编译该文件。这产生了一个名为 f3evtError.htm 的文件,它看起来像这样(针对内容进行了编辑):


错误事件

当控件检测到错误并且无法将错误信息返回给调用程序时发生。

语法

Private Sub object_Error( ByVal Number As Integer, ByVal Description As MSForms.ReturnString, _
    ByVal SCode As SCode, ByVal Source As String, ByVal HelpFile As String, _
    ByVal HelpContext As Long, ByVal CancelDisplay As MSForms.ReturnBoolean)

错误事件语法包含以下部分:

  • 对象:必需。有效的对象名称。
  • 索引:必需。与此事件关联的 MultiPage 中的页面索引。
  • 编号:必填。指定控件用来识别错误的唯一值。
  • 说明:必需。错误的文字说明。
  • S 代码:必需。指定错误的 OLE 状态代码。低 16 位指定一个与 Number 参数相同的值。
  • 来源:必填。标识启动事件的控件的字符串。
  • 帮助文件:必需。为描述错误的帮助文件指定一个完全限定的路径名​​。
  • HelpContext:必需。指定包含错误描述的帮助文件主题的上下文 ID。
  • 取消显示:必需。指定是否在消息框中显示错误字符串。

备注

为错误事件编写的代码决定了控件如何响应错误条件。

处理错误情况的能力因应用程序而异。当发生应用程序无法处理的错误时,将启动 Error 事件。


不幸的是,仅此而已。这是模糊的,因为该组件可以在许多不同类型的 ActiveX 主机中使用,并且错误捕获是主机实现的细节。我认为最后一段是你真正要问的。我想说这是相当安全的假设,因为 Office 文档没有提到它,Office 应用程序实际上不会触发此事件。事件在 VBA 编辑器中仍然可见的事实只是对象模型工作方式的副作用。编辑器没有简单的方法将其过滤掉,它只是显示对象的所有已发布事件。

【讨论】:

    【解决方案2】:

    所以,我调查了这个,因为我遇到了同样的问题。关于错误事件非常奇怪,但我能够找到一些关于它的信息。如果您在 IDE 的开发人员参考中查找错误事件,但不是离线内容是在线内容。这就是他们所说的: “当控件检测到错误并且无法将错误信息返回给调用程序时发生......当发生应用程序无法处理的错误时,将启动 Error 事件。” 现在这让我相信只有在出现一些灾难性错误时才会引发此事件。所以看起来你可能不走运。

    由于非基本代码,无法冒泡错误

    我的解决方法是让每个用户窗体都有自己的错误处理机制,这有点烦人,但这是我能做的最好的。除此之外,从某种意义上说,我的意思是 非常轻 并且与系统没有/有限的交互我能够在代码开始时执行 On Error Resume Next 并且一旦我卸载了用户表单检查If Err.Number>0 Then Err.Raise Err.Number,以便错误处理程序捕获它。但是,您可能知道,如果您选择第二个选项,请谨慎行事。

    希望对您有所帮助。让我知道你的决定。

    【讨论】:

      【解决方案3】:

      您可以在您的用户窗体代码(这是一个类)中捕获错误,然后在您的错误捕获代码中通过调用模块中的过程将错误详细信息传递给您的主代码。

      或者,您可以在其调用代码中声明您的 UserForm 变量 WithEvents,并在出现错误时引发您自己的错误事件。

      【讨论】:

      • 我担心不能在标准模块中声明UserForm变量WithEvents,它不会编译:编译错误:仅在对象模块中有效。
      • 对不起,我假设你是从另一个表单调用它,它是一个类模块。那么你需要选择第一个选项。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多