如何将VBA用户表单中的错误传递给调用方法

时间:2013-06-04 20:37:23

标签: vba userform

VBA用户表单中的错误(在initialize事件中发生的错误之外)似乎没有冒泡到调用方法。有没有办法强迫错误冒出来?

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实际做什么的任何文档。

3 个答案:

答案 0 :(得分:5)

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

UserForm对象由Microsoft Forms 2.0(一个ActiveX组件库)实现。这是一个向任何应用程序添加表单的通用库,它不仅限于Office应用程序。您可以在c:\ windows \ syswow64 \ fm20.dll(32位计算机的system32)上找到它。此组件的文档过去由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)

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

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

<强>说明

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

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


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

答案 1 :(得分:2)

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

由于非基本代码enter image description here

,无法冒泡错误

我的方法是让每个Userform都有自己的错误处理机制,有点烦人,但这是我能做的最好的。除此之外,在某些方面,我的意思是非常轻并且与系统没有/有限的交互我能够在代码的开头做一个On Error Resume Next并且我卸载了userform选中If Err.Number>0 Then Err.Raise Err.Number,以便错误处理程序捕获它。但是,您可能知道,如果您选择第二个选项,请谨慎行事。

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

答案 2 :(得分:1)

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

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