首页 > 解决方案 > 了解 for 循环 VBA 中的错误处理问题

问题描述

我写了一些例子来突出我的理解问题。

1. 示例:这按预期工作。错误通过Goto语句得到处理,错误处理返回到正常行为arfterwards

Sub ErrorHandlingWithoutLoop()
    Debug.Print "Before Error"
    On Error GoTo errorHandler
    
    Error (1)
    
    ' If no Error occured, the ErrorHandling procedure is skipped
    GoTo skip
    
errorHandler:
    Debug.Print "Handle Error"
    On Error GoTo 0
    
skip:
    Debug.Print "After Error"
    
    'Raise Error to see if error Handling is resumed to normal behavior
    Error (14)
End Sub

VBA 返回:

Before Error
Handle Error
After Error

并且错误处理恢复正常,通过抛出的错误可见 (14)

示例 2:我希望这个 sub 能够正常运行,并在最后一行抛出错误并显示错误 (14)。然而,在 n=2 的第二个循环中,错误处理无法按预期工作。为什么?

Sub ErrorHandlingWithLoop()
    Debug.Print "Before Error"

    For n = 1 To 10
        On Error GoTo errorHandler
        Error (1)
        
        ' If no Error occured, the ErrorHandling procedure is skipped
        GoTo skip
errorHandler:
        Debug.Print "Handle Error", n
        On Error GoTo 0
skip:
        Debug.Print "After Error", n
    Next n
    
    'Raise Error to see if error Handling is resumed to normal behavior
    ' -> This wont be reached though
    Error (14)
End Sub

VBA 返回:

Before Error
Handle Error   1 
After Error    1 

代码的执行在 n=2 的第二个循环中停止,抛出的错误为 1。最后的错误 14 不会被抛出

示例 3:我知道我可以通过添加“恢复跳过”语句来解决此问题。但是我不明白为什么这是必要的?

Sub ErrorHandlingWithLoopFixed()
    Debug.Print "Before Error"

    For n = 1 To 10
        On Error GoTo errorHandler
        Error (1)
        
        ' If no Error occured, the ErrorHandling procedure is skipped
        GoTo skip
errorHandler:
        Debug.Print "Handle Error", n
        On Error GoTo 0
        Resume skip
skip:
        Debug.Print "After Error", n
    Next n
    
    'Raise Error to confirm that error Handling is resumed to normal behavior
    Error (14)
End Sub

VBA 返回:

Before Error
Handle Error   1 
After Error    1 
Handle Error   2 
After Error    2 
Handle Error   3 
After Error    3 
Handle Error   4 
After Error    4 
Handle Error   5 
After Error    5 
Handle Error   6 
After Error    6 
Handle Error   7 
After Error    7 
Handle Error   8 
After Error    8 
Handle Error   9 
After Error    9 
Handle Error   10 
After Error    10 

并且错误处理恢复正常,通过抛出的错误可见 (14)

那么为什么需要跳过简历呢 ?! 感谢您的帮助=)

编辑: !奖励示例!3:有趣的是,如果我添加 a On Error Goto -1,那么 for 循环将无限循环。这是为什么?我不能押韵那个...

Sub ErrorHandlingWithLoop()
    Debug.Print "Before Error"

    For n = 1 To 10
        On Error GoTo errorHandler
        Error (1)
        
        ' If no Error occured, the ErrorHandling procedure is skipped
        GoTo skip
errorHandler:
        Debug.Print "Handle Error", n
        On Error GoTo -1
skip:
        Debug.Print "After Error", n
    Next n
    
    'Raise Error to see if error Handling is resumed to normal behavior
    ' -> This wont be reached though
    Error (14)
End Sub

VBA 返回:

Before Error
Handle Error   1 
After Error    1 
Handle Error   2 
After Error    2 
Handle Error   3 
After Error    3 
Handle Error   4 
After Error    4 
Handle Error   5 
After Error    5 
Handle Error   6 
After Error    6 
Handle Error   7 
After Error    7 
Handle Error   8 
...
...
...

这种情况一直持续到 Excel 崩溃。 对此也有任何帮助吗?

标签: vbafor-looperror-handling

解决方案


例如 2:您需要 Resume skip 的原因是错误处理程序仅“处理”一次并被停用。之后,您必须再次激活它,这正是 resume 所做的。

Paul Kelly将其命名为:“重置鼠标陷阱”,因为就像鼠标陷阱一样,错误处理程序在使用时会被停用,您需要手动激活它才能再次工作。所有这些都可以执行该任务(激活鼠标陷阱):恢复标签,恢复下一个,错误转到 -1。同样 On Error Resume Next 负责重新激活本身(您不需要为此手动执行此操作)。

对于奖励,无限循环的原因是你在结束之前有一个错误,但在它之前没有 Exit Sub。因此,每当您遇到该错误时,您都会被退回到您已放入循环中的错误处理程序中。一种更安全的方法是在退出子之后将错误处理程序放在最后。


推荐阅读