【问题标题】:VBA, Error Handling, Stack Overflow, Error Thrown After 2nd Loop PassVBA、错误处理、堆栈溢出、第二次循环通过后引发的错误
【发布时间】:2020-05-31 22:42:18
【问题描述】:

我的 VBA 代码中的实际堆栈溢出存在问题。

我正在尝试找出 VBA 错误处理。

我做了一个测试子来帮助解决这个问题。

我有一个 On Error GoTo Error_Handle

如果 Err.Number = 13 则重新开始,而不是 Resume Next。

如果我尝试循环 GoTo Start_Over_Label:,在第二次传递时仍然会抛出错误。

如果我尝试再次循环调用 sub,我会收到堆栈溢出错误。

有什么方法可以在 Sub 中循环,而不会引发错误或占用调用堆栈?

也许有办法 Resume Next,但重新启动 Sub?

我觉得有一个解决方案,但我想念它。

提前谢谢你

Private My_Long As Long
Private My_Err_Counter As Long

Private Function My_Timer(My_Delay As Long)

    Dim My_Timer_Counter As Long
    While My_Timer_Counter <= My_Delay
        DoEvents
        My_Timer_Counter = My_Timer_Counter + 1
    Wend

End Function

Sub My_Error_Test()
My_Start_Over:
    On Error GoTo My_Error_Handle
    My_Timer (200)

    My_Long = "as"
    MsgBox My_Long

My_Error_Handle:
    Debug.Print "Err Num: " & Err.Number & " - " & Err.Description
    Debug.Print My_Err_Counter
    My_Err_Counter = My_Err_Counter + 1
    If Err.Number = 13 Then
        Err.Clear
        GoTo My_Start_Over
    End If
End Sub

【问题讨论】:

  • doevents 如果使用不当,经常会通过递归到事件处理程序中导致堆栈溢出。另一件事是recusion本身,但它需要很多级别。您可以计算的最小堆栈是 1 MB 的存储空间。

标签: vba


【解决方案1】:

关键问题是你应该使用Resume My_Start_Over 而不是GoTo My_Start_Over。 GoTo 不会重置错误处理

您可能希望解决的其他问题

  • 通常你会在错误处理程序之前有一个Exit Sub。没有它,错误处理程序代码将在 Sub 到达该点时执行。
  • 不要在Sub 的参数周围使用()(除非您想要ByRef 参数覆盖为ByVal
  • While / Wend 已弃用。请改用Do While Loop
  • 首选本地参数
  • 我添加了一些代码,以便您的测试最终完成
Private Function My_Timer(My_Delay As Long)
    Dim My_Timer_Counter As Long

    Do While My_Timer_Counter <= My_Delay
        DoEvents
        My_Timer_Counter = My_Timer_Counter + 1
    Loop
End Function

Sub My_Error_Test()
    Dim My_Long As Long
    Dim My_Err_Counter As Long
    Dim v As Variant
    v = "as"

My_Start_Over:

    On Error GoTo My_Error_Handle
    My_Timer 200
    If My_Err_Counter > 100 Then v = 1

    My_Long = v
    MsgBox My_Long
    My_Err_Counter = 0
Exit Sub
My_Error_Handle:
    Debug.Print "Err Num: " & Err.Number & " - " & Err.Description
    Debug.Print My_Err_Counter
    My_Err_Counter = My_Err_Counter + 1
    If Err.Number = 13 Then
        Err.Clear
        Resume My_Start_Over
    End If
End Sub

【讨论】:

  • 非常感谢 Chris 抽出宝贵时间给我这些有用的提示。 Resume Start_Over_Label 是缺失的部分。我也会采纳你的其他建议。
猜你喜欢
  • 1970-01-01
  • 2013-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-26
  • 2019-02-16
  • 2011-09-10
  • 1970-01-01
相关资源
最近更新 更多