【问题标题】:How to manage the no error case when handling errors in VBA? [duplicate]在 VBA 中处理错误时如何管理无错误情况? [复制]
【发布时间】:2012-04-25 20:16:37
【问题描述】:

我需要使用GoTo 语句捕获一些 VBA 错误:

Sub mySub
 On Error GoTo errorHandler:
    Workbooks.Open("myWorkbook")
'
' Some Code
'
errorHandler:
MsgBox "ERROR"

End Sub

问题是当没有错误时,errorHandler 部分会被执行。
我找到了this discussion,但答案并没有解决我的问题。
我尝试按照说明添加Exit Sub 语句:

Sub mySub
 On Error GoTo errorHandler:
    Workbooks.Open("myWorkbook")
    Exit Sub

'
' Some Code
'
errorHandler:
  MsgBox "ERROR"

End Sub

在这种情况下,它会在没有错误时退出该方法。 我也试过了:

 Sub mySub
 On Error GoTo errorHandler:
    Workbooks.Open("myWorkbook")
'
' Some Code
'
errorHandler:
  MsgBox "ERROR"
  Exit Sub
End Sub

但还是同样的问题:errorHandler 即使没有发生错误也会被执行。

【问题讨论】:

    标签: excel vba error-handling


    【解决方案1】:

    只需将 Exit sub 放入即可。

    Sub mySub
     On Error GoTo myHandler:
        Workbooks.Open("myWorkbook")
    '
    ' Some Code
    '
    Exit sub
    
    myHandler:
    MsgBox "EROOR !"
    
    err.clear
    End Sub
    

    【讨论】:

    • 可以添加On Error Goto 0这一行吗?所以 OP 明白重置错误重定向是一个很好的做法......赞成:)
    • @Marco 你的意思是 err.Clear 吗?这是 VBA。
    • @Remou:也许我错了,但我记得我(很多年前)使用On Error Goto 0 使代码在没有错误检查的情况下运行。我记得使用这条指令来避免不可预知的 jumps 以后的错误是一个很好的做法...我搜索了 Google 看看我是否错了,但 here 我发现一篇文章给了我 @ 987654326@...
    • @Marco:我认为没有理由使用On Error GoTo 0,而且我也从未在错误处理程序中看到过它......我在ExitProcedure: 类型的东西中看到过它(@ 987654322@) 以避免无限错误处理“循环”。
    • On Error GoTo 0 关闭错误处理,告诉 VB/VBA 停止并在遇到错误时抛出错误消息。它还(隐式地)清除错误条件。在像这样的简单情况下,使用它可能没有缺点,但在其他情况下,如果您想捕获错误,处理它然后恢复处理,您肯定不想使用 GoTo 0。即使在这个简单的情况,没有任何优势;总的来说,我会说,这是一个不好的习惯。
    【解决方案2】:
    Public Sub MySub
        On Error Goto Skip
    
        ' Some Codes
    
    Skip:
        If err.Number > 0 Then
    
            ' Run whatever codes if error occurs
    
            err.Clear
        End If
        On Error Goto 0
    End Su
    

    【讨论】:

      【解决方案3】:

      这是我喜欢的模式:

      Sub SomeSub()
          On Error GoTo ErrorLabel
      
          'Code goes here
      
      ExitLabel:
         'Clean-up code, if any, goes here 
         Exit Sub
      
      ErrorLabel:
          'Error-handling code goes here
          Resume ExitLabel
      End Sub
      

      请注意,Resume 会清除错误。我喜欢这种模式有几个原因:

      1. 习惯性地在错误处理块之前插入退出块可以减少我遇到 OP 意外掉入错误处理程序问题的机会。
      2. 我使用GoTo ExitLabel any 提前退出子或函数。这样,我不太可能意外跳过清理代码。示例:

        Sub SomeOtherSub()
            Dim x As ResourceThatNeedsToBeClosed
            Dim i As Long
            On Error GoTo ErrorLabel
            Set x = GetX
            For i = 1 To 100
                If x.SomeFunction(i) Then
                    GoTo ExitLabel
                End If
            Next
        ExitLabel:
            x.Close
        ErrorLabel:
            'Error-handling code goes here
            Resume ExitLabel
        End Sub
        

      【讨论】:

      • 是的,我也喜欢这个。它似乎也是自动插入错误处理块的应用程序的标准。我什至有一些代码要删除并以这种格式创建大纲错误处理。
      【解决方案4】:

      在错误处理程序部分使用以下代码:

      if err.number>0 the
          ' error handling goes here
      else
          ' some code
      end if
      

      【讨论】:

        【解决方案5】:

        我遇到了和你一样的问题,上面的解决方案没有用。他们显然甚至没有看到您已经在原始帖子的 2 个不同位置写了 Exit Sub。似乎没有在线网站理解有时不会出现错误(如果总是会出现错误,你为什么要这样编码?),当没有错误时,你显然不会想退出子。您也不希望 myHandler 在没有错误时运行。呃!这是我想出的似乎可行的解决方案。

        On Error GoTo ErrorHandler
        'This is the thing I am trying to do...
        Workbooks("SpreadSolver.xlsb").Activate
        'If it works, great. 
        'Don't touch the error stuff and move on. 
        'I.e. go to the part that I know works (the rest of the macro)
        GoTo ThisPartWorks
        
        'If the thing I am trying to do doesn't work...
        ErrorHandler:
        MsgBox "Error: Please open Spread Solver and then run the macro."
        'Only want to Exit Sub if there is an error.. duh.
        Exit Sub
        
        ThisPartWorks:
        'the rest of your macro can go here...
        '...
        End Sub
        

        【讨论】:

        • 无论有没有错误,接受的答案都应该有效,这实际上是在 VBA 中处理错误的正确方法。另一方面,使用GoTo 移动代码被认为是非常糟糕的做法,特别是如果您将使用多个GoTo 语句。
        • OP 将Exit Sub 放在两个错误的不同位置。你只需要把它放在正确的位置(即在你的错误处理代码之前)。
        【解决方案6】:

        我在 ErrorHandler 中使用 If 语句,如果没有错误,它将停止执行。这是通过使用 Err.Number (Err (object) number (e.g. Run-time error 9: Subscript out of range))实现的

        If Err.Number >= 1 Then
        MsgBox ("Message")
        End
        Else: other code
        End If
        Exit Sub
        

        【讨论】:

          【解决方案7】:

          这就是我所做的。像魅力一样工作

          Sub someProgram ()
              On Error goto Handler:
                  x = 7/0
          
              'Some code you wanna execute  with or without error
          Exit Sub
          
          Handler:
               'Write your handler here
          
          Resume next 'After handling error, this line will help you resume the next line
          
          End sub
          

          【讨论】:

            【解决方案8】:
            sub XYZ ()
            on error goto label
            
            "Write your macro"
            
            Label:
                  If Err.Description <> "" Then
                   "your code if error occurs for eg:"
                   msgbox "Error Occured!"
                   Exit Sub
                   Else
                   "Your code when no error occurs for eg"
                    msgbox " Done."
                   End If
            Exit Sub
            

            【讨论】:

            • 请在您的答案中添加一些解释,以便其他人可以从中学习
            • 虽然此代码可以解决问题,including an explanation 说明如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提出问题的人。请edit您的回答添加解释并说明适用的限制和假设。
            猜你喜欢
            • 1970-01-01
            • 2014-02-20
            • 1970-01-01
            • 2013-06-06
            • 1970-01-01
            • 2015-02-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多