9

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 实际作用的文档。

4

3 回答 3

5

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

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

我发现的一种解决方法是使用 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 中与此事件关联的页面的索引。
  • 编号:必填。指定控件用来识别错误的唯一值。
  • 说明:必填。错误的文本描述。
  • SCode:必填。指定错误的 OLE 状态代码。低 16 位指定与 Number 参数相同的值。
  • 来源:必填。标识启动事件的控件的字符串。
  • 帮助文件:必需。为描述错误的帮助文件指定一个完全限定的路径名​​。
  • 帮助上下文:必需。指定包含错误描述的帮助文件主题的上下文 ID。
  • 取消显示:必需。指定是否在消息框中显示错误字符串。

评论

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

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


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

于 2013-08-06T02:57:49.780 回答
2

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

由于非基本代码,无法冒泡错误在此处输入图像描述

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

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

于 2013-08-06T00:15:56.100 回答
1

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

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

于 2013-08-01T00:02:44.053 回答