如何在VB6中重新启用默认的错误处理

8
我有一些代码,在几个地方使用了各种“On Error Goto”错误处理程序来处理某些损坏的第三方硬件。在一个没有错误陷阱但由一个拥有错误陷阱的例程调用的例程中,我遇到了一个溢出错误(从Err变量读取)。我一直认为错误陷阱只在它们声明的例程中有效,但看起来子例程中的错误会导致它进入调用函数的错误陷阱。
所以我关闭了调用函数的错误陷阱,找到了我的溢出问题,一切都好了。但在这样做之前,我花了一些时间尝试找到一种程序化的方法来让VB在那个例程内返回其默认的错误处理方式(这样我就不必修改外部代码进行调试),但是我找不到。我能找到的唯一的错误命令是:
On Error GoTo [label] On Error Resume Next On Error Goto 0 On Error GoTo -1
所有这些都打开手动错误处理-有没有办法将其关闭(恢复到VB6默认值)?
8个回答

10

在 VB6 手册的错误处理层次结构章节中对此做了详细解释。 On Error Goto 0 禁用了当前过程中的错误处理程序,而非调用它的过程中的错误处理程序。

如果一个过程发生错误,而且 这个过程没有启用错误处理程序, Visual Basic 将会向后搜索调用列表中的待定过程,并执行它找到的第一个已启用的错误处理程序。如果它在调用列表中找不到已启用的错误处理程序,则显示默认的意外错误信息并停止执行。

正如其他人所说,你可以进入工具-选项-常规选项卡,选择断点停在所有错误处。这有效地禁用了所有的 On Error 语句 - IDE 每次出错都会立即停止运行。

如果你的 VB6 代码在正常操作中会抛出一些错误,那么这可能会令人烦恼。例如当你检查文件是否存在时,或者当用户在通用对话框中按下取消键时。你不希望 IDE 在这些行上每次都停止运行。但是,你可能在所有的事件处理过程中都有样板式的错误处理程序,以防止程序在出现意外错误时崩溃。但是,在调试问题时,它们可能会成为麻烦,因为 IDE 不会在出错的行上停止运行。一个技巧是在 IDE 中关闭这些错误处理程序,但在构建的可执行文件中保留它们。你可以按照以下步骤操作。

将这些函数放入一个模块中。

Public Function InIDE() As Boolean 
  Debug.Assert Not TestIDE(InIDE) 
End Function 

Private Function TestIDE(Test As Boolean) As Boolean 
  Test = True 
End Function 

然后你可以像这样编写错误处理程序。

Private Sub Form_Load() 
  If Not InIDE() Then On Error Goto PreventCrashes 
  <lots of code> 
  Exit Sub 

PreventCrashes: 
  <report the error> 
End Sub 

内容引自这里。另一个提示是,使用免费的插件MZTools自动添加这些样板式错误处理程序。对于生产质量的代码,你可以在每个程序中进一步添加错误处理程序以创建简陋的堆栈跟踪。您还可以在每个错误处理程序中立即记录错误。

编辑:Ant正确指出On Error Goto -1VB.Net语句,在VB6中无效。

编辑:Arvo和OneNerd撰写了一些关于在VB6错误处理中模拟Finally清理块的有趣讨论。在此问题的讨论也值得一看。


3

重置错误状态的方法非常清晰简单 - 使用关键字 Resume。有三种可能:

Resume
Resume Next
Resume <Label>

当出现错误时,Resume命令会在错误行继续执行,而Resume Next命令会在下一行继续执行,而较少使用的Resume Label命令会在指定标签处继续执行。这对于在VB6中创建类似try-catch-finally结构非常有用。该答案来自OneNerd并经过修改。

Function MyFunction() as String

'-- start of error block
'
 On Error Goto Catch
   ' do something here that might cause an error
   MyFunction = "IT WORKED"
   Goto Finally

   Catch:
   ' error occured - do something else
   MyFunction = Err.Description
   Err.Clear
   Resume Finally          ''added to clear error status

 Finally:
   On Error Resume Next    ''added to avoid repeated errors
   ' put your finally code here

 '
 '-- end of error block

End Function

如果在Finally块中发生一些后续错误,简单的Err.Clear并不起作用;但Resume Finally可以重置内部错误状态。


On Error Resume Next 也会重置内部错误状态,因此 Err.Clear 和 Resume Finally 是多余的。个人认为 Goto Finally 更清晰明了。最重要的是,在 End Function 之前放置 Err.Clear 或 On Error Goto 0,否则 Finally 块中的任何错误状态都会返回给调用者!! - MarkJ
On Error Resume Next本身(在错误之后)不会重置错误状态。我刚刚测试了一下,确实如此。 - Arvo

1
这是我所做的:
首先,在您的 Sub Main()Sub Form_Load() 子程序中,如有必要,请打开错误处理:
'-- turn on error handling
'
On Error GoTo 0
'
'-------------------------

现在将打开错误提示。

接下来,结合On Error Resume NextOn Error GoTo {label}命令以及Err对象使用。以下是模拟try/catch/finally的示例:

Function MyFunction() as String

'-- start of error block
'
 On Error Goto Catch
   ' do something here that might cause an error
   MyFunction = "IT WORKED"
   Goto Finally

   Catch:
   ' error occured - do something else
   MyFunction = Err.Description
   Err.Clear

 Finally:
   ' put your finally code here

 '
 '-- end of error block

End Function

+1 在“Finally”块中,如果错误干扰了需要拆除的任何内容的设置,您可能需要使用On Error Resume Next。而且我不明白为什么您在Form_Load/Sub Main中放置了On Error Goto 0? - MarkJ

1

有一个方便的右键菜单,可以让您打开或关闭错误处理。只需在代码窗口上右键单击,然后选择“切换”,接着您可以选择“在所有错误处中断”。这将禁用所有“On Error”语句。


0
on error goto 0

应该是你想要的...它应该会引发错误,然后可能会展开到RTL...

虽然已经过了很长时间,但我相当确定这就是你想要的。

on error resume next

将会直接跳到下一条语句,所以你需要有足够的

if err.Number <> 0 then

你的代码中可能出现错误的语句...


不正确的LarryF。On Error Goto 0会禁用程序本身中的错误处理程序,但运行时会向上查找调用堆栈以寻找任何活动的错误处理程序。如果有一个,它将处理该错误。 - MarkJ
糟糕..我的错。我可能在想vbScript,它会像描述的那样行事..或者至少曾经是这样。(我不知道最新版本是什么,它是否最近有所改变..) - LarryF

0

/工具/选项/常规/错误处理


0

必须同意LarryF的观点,On Error Goto 0应该关闭已经通过On Error Resume Next打开的显式错误处理。但是,函数和子程序确实有自己的范围。来自Microsoft的Dr. Scripto

在脚本的开头放置On Error Resume Next,就像我们经常做的那样,使其适用于整个脚本主体。但是,正如我们将在后面的示例中看到的那样,它的范围不包括函数或子例程。如果您想在函数或子例程中处理错误,则必须在每个函数或子例程中也包含On Error Resume Next,然后再检查Err对象。

您可以使用On Error GoTo 0关闭错误处理。因此,您可以在要检查Err对象之前使用On Error Resume Next打开错误处理,然后使用On Error GoTo 0关闭错误处理。


额,但是Scripto博士在谈论VBScript,而问题是关于VB6的。 - MarkJ

0

没有 "On Error GoTo -1" 这个语句,所以我不知道你从哪里得到的。

VB6 异常处理在手册中有非常详细的介绍。


1
我认为这是一个VB.NET语句:http://msdn.microsoft.com/zh-cn/library/5hsw66as(VS.80).aspx - Ant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接