【问题标题】:Indentation of Error Handler in Excel VBAExcel VBA 中错误处理程序的缩进
【发布时间】:2017-03-23 10:58:49
【问题描述】:

这是一个非常挑剔的问题:我在 Excel VBA 的 For To 循环中插入了一个错误处理程序;我希望循环的内容缩进,这样:

For i = 0 to n
    On Error GoTo ErrorHandler:
        '~~> code here
    ErrorHandler:
        '~~> code here
        Resume NextLoop
    NextLoop:
Next

但是,Excel VBA 会自动取消错误处理程序的缩进:

For i = 0 to n
    On Error GoTo ErrorHandler:
        '~~> code here
ErrorHandler:
        '~~> code here
        Resume NextLoop
NextLoop:
Next

我尝试在“工具”>“选项”>“编辑器”中取消选择“自动缩进”选项,但没有成功。

如何避免这种情况?

【问题讨论】:

  • 您无法控制 Excel 中标签的缩进。它默认并固定在左侧。这样做的原因是让它们更容易被发现
  • 我看到了@Victor Moraes。有什么办法可以规避吗?
  • 我真的不知道,但我可以问一下,除了“我觉得那样更漂亮”之外,你为什么要这样做?
  • "Circumvent"... 重写以另一种方式处理错误,无需Goto 语句。
  • 这真的是@Victor Moraes 的唯一原因,这就是为什么我说这是一个“挑剔的问题”。好的,谢谢。

标签: excel error-handling vba


【解决方案1】:

编辑原来的代码有一个粗心的错误。感谢 user2426679 给我机会修复它。

原帖

使用GoTo Label 的代码对于理解和避免错误来说可能是一场噩梦。我知道GoTo Label 可能适用的唯一情况是致命错误退出,没有返回的意图。跳出错误并试图跳回去是很难正确的,当你在几个月后返回时很难理解。

您的代码中是否有多个语句会引发错误?如果是这样,错误处理程序如何知道它正在处理哪个错误?

我赞成:

On Error Resume Next                ' Suspend normal error handling
Statement that might throw an error
On Error GoTo 0                     ' Restore normal error handling
If Err.Number <> 0 then
  ' Code to handle error
End If

Err.NumberErr.Description 的值将告诉错误是什么,并允许编写特定的错误处理代码。

有些人认为,从主代码中去除错误处理可以保持主代码的整洁。这个论点有一些优点。如果有几十个潜在错误,分析可能会变得复杂,并使正常路径难以隔离。但是,根据我的经验,这是非常不寻常的。也许,您有一个文件列表,其中一些可能无法打开。文件打开的原因有很多,但您的代码对它们无能为力。它所能做的就是显示Err.Description 并移动到下一个文件。

新文本和代码

除了代码中的错误之外,我现在认为我原来的帖子中没有任何内容不正确。但是,我认为原始帖子没有应有的完整。

如果您搜索“VBA Err.Number”,您会找到列出 VBA 错误处理代码的网站。由于这些网站来来去去,我不会推荐我最喜欢的。但是,我尝试生成错误以查看会发生什么。考虑这段代码:

Option Explicit
Sub DemoErrorHandling()

  Dim ErrDesc As String
  Dim ErrNum As Long
  Dim FileNum As Long
  Dim PathFile As Variant

  FileNum = FreeFile

  For Each PathFile In Array("", "X:", "C:\Program Files\Common Files\Intel\" & _
                             "WirelessCommon\libeay32.dll")

    On Error Resume Next
    Open PathFile For Input As FileNum
    ErrNum = Err.Number
    ErrDesc = Err.Description
    Close FileNum
    On Error GoTo 0
    Debug.Print """" & PathFile & """ gives error:"
    Debug.Print "  A " & Err.Number & " " & Err.Description
    Debug.Print "  B " & ErrNum & " " & ErrDesc

  Next

End Sub

在我的系统上,输出:

"" gives error:
  A 0 
  B 75 Path/File access error
"X:" gives error:
  A 0 
  B 76 Path not found
"C:\Program Files\Common Files\Intel\WirelessCommon\libeay32.dll" gives error:
  A 0 
  B 0 

注意,正如用户 2426679 指出的那样,On Error GoTo 0 已清除 Err.NumberErr.Description。只有将这些值保存在变量中,它们才能用于测试。请注意,尝试打开空文件名和不存在的光盘会产生不同的错误。

我的代码演示了您可以循环尝试不同的文件,直到一个文件成功打开。您可以一直向用户询问文件,直到打开时没有错误。

【讨论】:

  • 这不起作用:Err.NumberOn Error GoTo 0 之后被重置
  • @user2426679 感谢您的提醒。您认为我的编辑是否充分纠正了我的错误?
  • yes,但我通常讨厌 VBA 的错误处理(缺乏),因为 (1) MS 文档不够全面,无法了解所有错误编号,这就是为什么您必须求助于您在上面所做的“数字发现”,并且 (2) 这会迫使您进入代码通常等同于 try ... catch(all) 的位置,而您永远不会这样做另一种语言。因此,我选择在On Error GoTo myHandlerOn Error GoTo 0 之间放置不超过一行代码;我只需要对它们之间的错误线有 100% 的信心。
  • @user2426679 我同意,VBA 的错误处理很笨拙,我尽可能多地测试可能的错误以避免需要它。和你一样,我一次只测试一个语句,我别无选择,只能包含它..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-25
  • 1970-01-01
  • 1970-01-01
  • 2011-08-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多