【问题标题】:VBA Exception Slipping Through HandlerVBA 异常通过处理程序
【发布时间】:2023-03-10 07:08:01
【问题描述】:

我继承了一个可怕 Excel VBA 应用程序,它是由一个显然不喜欢函数和cmets 的人编写的。打开源代码就像凝视着一个疯狂的深渊,有 9 级 hell 缩进等待着粗心大意的人。

首先,设置。

在调试间歇性问题的过程中,我已将主要功能中的特定行确定为其位置。由于该异常对我来说不容易修复,因此我给了这一行,并且只有这一行,一个显示自定义消息的错误处理程序。

    ' Lots of stuff cut out
    On Error GoTo TechReleaseBuildError
    lb_Err1 = BuildDirectories(gj_TechBld.mt_TechRlsOutDir)
    On Error GoTo 0
    ' Lots of stuff cut out
    Exit Sub
TechReleaseBuildError:
    MsgBox "Error building tech release. Pause the synchronization software and try again."
    Stop
    Resume
End Sub

StopResume 仅用于帮助调试,因为弹出的正常错误消息没有调试错误的选项。

BuildDirectories 函数中,我确定了导致错误的一行,该错误被踢到主要函数。我也在这个函数中放置了错误处理程序。

    ' Lots of stuff cut out
    Exit Function
TEST:
    Stop
    Resume

SynchroRetry:
    Dim CurrentError As ErrObject
    CurrentError = Information.err
    SynchroRetryCounter = SynchroRetryCounter + 1
    Debug.Print "Synchro Error, retrying #" + SynchroRetryCounter
    Stop
    If SynchroRetryCounter > 5 Then
        Stop
        Information.err.Raise CurrentError.Number, CurrentError.Source, CurrentError.Description, CurrentError.HelpFile, CurrentError.HelpContext
    Else
        Application.Wait Now + #12:00:03 AM#
        Resume
    End If

End Function

BuildDirectories 的开头,我放置了一个On Error GoTo TEST 语句作为包罗万象的错误处理程序,这样我就可以识别它们来自哪些行,并且还对我已经使用的一行使用了 SynchroRetry 处理程序知道会导致问题,我立即将其重置回 TEST 处理程序。 SynchroRetry 处理程序只需等待 3 秒并重试,在第 5 次重试后失败。

' For some reason, this line (and only this line so far) causes problems when synchronization software is running.
' The error handler waits for a few seconds then tries again a few times.
Dim SynchroRetryCounter As Integer
SynchroRetryCounter = 0
On Error GoTo SynchroRetry
lj_FSO.CopyFile Source:=lt_RPOFilePath & lt_RPOFileName, Destination:=lt_VinRposDir & "\" & lt_RPOFileName, OverWriteFiles:=True ' Trouble line
On Error GoTo TEST

我已经用 Find 验证了这些是函数中仅有的 3 个 On Error 语句(甚至是模块中唯一的语句)。除了显示的两个之外,顶级函数也没有On Errors

简而言之,顶级函数只有一行有一个错误处理程序,而它所包含的函数内部也有两个错误处理程序,一个用于其已知的麻烦行之一,另一个用于应该包含的通用行整个函数。

问题是发生了一些错误,导致我的“错误构建技术版本”。要显示的消息,但似乎没有触发 TEST 或 SynchroRetry 错误处理程序。我无法想象这是怎么可能的。我对 VBA 的错误处理模型的怪物相对较新,但我不相信我做错了什么。我在这里错过了一些微妙之处吗?异常如何能够绕过我的处理程序并像这样冒泡堆栈?我不相信函数值的赋值或传递会导致问题,因为它们只是一个布尔值和字符串值。该问题也是间歇性的,仅当我们在该程序将文件复制到的目录上启用了文件同步软件时才会出现此问题。

【问题讨论】:

  • 我发现您的每个代码示例都很难理解,因为它迫使我假设过程的名称。如果您更新您的问题以显示名称,加上“错误时”的内容,以及对其他函数/子的任何调用,那将是最好的。此外,在 VBA 中,您在“工具 |”中有什么设置?选项 |错误处理的常规选项卡?
  • 您提到在BuildDirectories 中使用两个错误处理程序,在两者之间切换。是否有可能某些 Resume 语句应该改为 Resume Next,关于您认为应该立即重置回 TEST 处理程序的位置?
  • 另外,SynchroRetry 处理程序中的 Information.err.Raise CurrentError.Number,... 位,您是否希望 TEST 处理程序捕获它?
  • @rskar 不,在此处引发错误意味着故意将其扔到堆栈中。

标签: vba excel error-handling exception-handling


【解决方案1】:

因此,在我发布此内容几个小时后,我设法弄明白了。

错误框上没有“调试”按钮的原因是,在“选项”中,错误捕获设置为“在未处理的错误时中断”。将其更改为“Break in Class Module”会使按钮恢复原状。

异常绕过我的错误处理程序的原因是它们发生在我的 SynchroRetry 错误处理程序中。特别是,我不得不改变前几行:

Dim CurrentError As ErrObject
CurrentError = Information.err
SynchroRetryCounter = SynchroRetryCounter + 1
Debug.Print "Synchro Error, retrying #" + SynchroRetryCounter

到这里:

Dim CurrentError As New ErrObject
Set CurrentError = Information.err
SynchroRetryCounter = SynchroRetryCounter + 1
Debug.Print "Synchro Error, retrying #" + CStr(SynchroRetryCounter)

注意NewSetCStr的添加。

问题解决了。

【讨论】:

    猜你喜欢
    • 2012-02-06
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 2020-12-19
    • 2017-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多