【问题标题】:VBA subfunctions Error handlingVBA 子函数 错误处理
【发布时间】:2014-08-21 07:17:27
【问题描述】:

我有一个需要帮助的简洁示例。我正在尝试找到一种方法来处理我的错误但保持我的子功能模块化(不需要知道我的其余代码才能正常工作)

在 Excel VBA 中,没有 Try/Catch 功能。 VBA 中有本机函数,如果它们失败则返回错误。我希望使以下示例整洁

Function wrapperForFunction(input As Variant) As Boolean
  On Error goto returnTrue
  fancyFunctionThatReturnsError(input As Variant)
  wrapperForFunction = False
  LINE OF CODE THAT SETS ERROR BACK TO WHAT IT WAS BEFORE CHANGING IT TO returnTrue
  Return
returnTrue:
  wrapperForFunction = True
  LINE OF CODE THAT SETS ERROR BACK TO WHAT IT WAS BEFORE CHANGING IT TO returnTrue
End Function

Sub MainProgram()
  On Error goto errorHandlerMain
  '' do stuff
  if wrapperForFunction(input) then 'do stuff
  '' do morestuff
  if wrapperForFunction(input) then 'do stuff
errorHandlerMain:
  'non-erroring cleanup code
End Sub

Sub NestedSub()
  On Error goto errorHandlerNestedSub
  '' do stuff
  if wrapperForFunction(input) then 'do stuff
errorHandlerNestedSub:
  'non-erroring cleanup code      
End Sub

我要避免的是这种解决方案

Function wrapperForFunction(input As Variant) As Boolean
  On Error goto returnTrue
  fancyFunctionThatReturnsError(input As Variant)
  wrapperForFunction = False
  Return
returnTrue:
  wrapperForFunction = True
End Function

Sub MainProgram()
  On Error goto errorHandlerMain
  '' do stuff
  tmp = wrapperForFunction(input) ' <------------ THIS LINE WAS ADDED 
  On Error goto errorHandlerMain   ' <------------ THIS LINE WAS ADDED 
  if tmp then 'do stuff
  '' do morestuff
  tmp = wrapperForFunction(input) ' <------------ THIS LINE WAS ADDED 
  On Error goto errorHandlerMain   ' <------------ THIS LINE WAS ADDED 
  if tmp then 'do stuff
errorHandlerMain:
  'non-erroring cleanup code
End Sub

Sub NestedSub()
  On Error goto errorHandlerNestedSub
  '' do stuff
  tmp = wrapperForFunction(input) ' <------------ THIS LINE WAS ADDED 
  On Error goto errorHandlerNestedSub   ' <------------ THIS LINE WAS ADDED 
  if tmp then 'do stuff
errorHandlerNestedSub:
  'non-erroring cleanup code
End Sub

有什么建议吗??有没有办法找出当前的“On Error goto x”状态并将其重置为更改之前的状态? 喜欢在

Function foobar()
  Dim errorLine As Long: errorLine = CURRENT_ERROR_LINE
  On Error goto 40
  'do stuff
  On Error goto errorLine
  Return
40'cleanup code

End Function

【问题讨论】:

标签: vba error-handling nested


【解决方案1】:

关于 VBA 中的错误处理需要注意的几点:

  • On Error Goto &lt;x&gt; 语句的范围是包含该语句的过程以及从该过程中调用的任何过程。
  • 作为对上一点的扩展:如果发生错误,它将“冒泡”调用堆栈,直到到达定义了错误处理的过程,如果堆栈上没有定义错误处理的过程,它将显示通用消息框。

考虑到上述行为,无需在每次调用过程后重新声明On Error Goto &lt;x&gt;,因为被调用过程对其错误处理所做的任何更改都将在其完成时超出范围。

使用以下示例:

Public Sub Subroutine1()
    Dim a As Double, b As Double, c As Double

    On Error GoTo Err_Subroutine
    a = 10
    b = 2

    c = Divide(a, b)
    c = c / 0        

Exit_Subroutine:
    Exit Sub

Err_Subroutine:
    Select Case Err.Number
        Case 11 'DIV/0
            MsgBox "DIV/0 error in Sub Subroutine1()"
            Resume Exit_Subroutine
        Case Else
            MsgBox "Unhandled error in Subroutine1()"
            Resume Exit_Subroutine
    End Select
End Sub

'Returns a/b or 0 if an error occurs
Public Function Divide(a, b)
    On Error GoTo Err_Divide

    Divide = a / b

Exit_Divide:
    Exit Function

Err_Divide:
    Select Case Err.Number
        Case 11 'DIV/0
            MsgBox "DIV/0 error in Function Divide()"
            Divide = 0
            Resume Exit_Divide
        Case Else
            MsgBox "Unhandled error in Function Divide()"
            Divide = 0
            Resume Exit_Divide
    End Select
End Function

尽管调用了Divide 并执行了语句On Error GoTo Err_Divide,但当下一行发生DIV/0 错误时,错误仍将定向到Err_Subroutine

【讨论】:

  • 可能还值得注意的是,On Error GoTo 0 将错误处理返回到其默认状态,即在当前范围内未处理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-15
  • 2011-06-19
  • 2023-03-29
  • 1970-01-01
  • 2014-02-20
  • 2017-08-24
  • 2012-03-03
相关资源
最近更新 更多