【问题标题】:On Error Resume Next seemingly not workingOn Error Resume Next 似乎不起作用
【发布时间】:2013-03-17 09:37:42
【问题描述】:

我有以下两行代码:

On Error Resume Next
myWorkbook.Sheets("x").Columns("D:T").AutoFit

我已进入宏并执行On Error Resume Next 行,然后在下一行myWorkbook... 执行以下操作:

为什么编译器不恢复下一行代码?

On Error 在整个程序代码中被广泛使用;我意识到最好的做法是尽可能少地使用它,但它似乎符合这个宏的目的。

阅读此SO QUESTION 表示您不能在另一组中设置一组错误捕获。我如何保证在代码继续之前已经“关闭”了一组错误捕获 - On Error Goto 0 是否重置错误捕获?如果它确实重置了,那么为什么不恢复以下工作?:

Sub GetAction()
Dim WB As Workbook
Set WB = ThisWorkbook

On Error GoTo endbit:
'raise an error
Err.Raise 69
Exit Sub
endbit:
On Error GoTo 0

On Error Resume Next
WB.Sheets("x").Columns("D:T").AutoFit

End Sub

【问题讨论】:

  • 我们可以看看完整的代码吗?
  • @brettdj 所有 500 行!
  • @brettdj 你认为我需要确保关闭之前代码中的所有其他错误捕获吗?
  • 是的 :) 我认为你已经有一个错误。
  • @Remou - Re.your 编辑:这个错误代码不是对所有 VBA 实现都通用吗?

标签: excel vba


【解决方案1】:

还有一个 VBA 设置会导致 On Error ... 语句被忽略并且该对话框始终出现。有关检查/更改选项的更多详细信息,请参阅此答案:https://stackoverflow.com/a/3440789/381588

【讨论】:

  • ?正如您从屏幕打印中看到的那样,错误并没有被忽略。但是On Error Resume Next 似乎被忽略了。
  • @whytheq 当错误捕获设置设置为“Break on All Errors”时 - 即使存在活动的错误处理程序,错误对话框也会针对 所有 错误显示,这似乎正是您所经历的。
  • 感谢值得记住 - 但它不在那个设置上 - 它在 Break on All Unhandled Errors
【解决方案2】:

初始错误未关闭时的错误示例。

Sub GetAction()
Dim WB As Workbook
Set WB = ThisWorkbook
On Error GoTo endbit:
'raise an error
Err.Raise 69
Exit Sub
endbit:
On Error Resume Next
WB.Sheets("x").Columns("D:T").AutoFit
End Sub

【讨论】:

  • 如果我在endbit: 行之后添加On Error GoTo 0,简历仍然不起作用!这是否意味着@grahamj42 的答案是错误的?
【解决方案3】:

如您所见,在同一函数或子例程中,On Error Resume Next 不会覆盖 On Error Goto ...(如果它仍然处于活动状态)。

On Error Goto 0 恢复默认错误处理程序是正确的。

在某些情况下,On Error 是处理异常情况的最合适方法。我更喜欢使用以下结构:

On Error Resume Next

statement which might fail

On Error Goto 0

if statement has failed then ...

这将所有内容放在一起,但在其他情况下,在过程结束时使用通用错误处理程序可能会更好。

【讨论】:

  • +1 谢谢 - 几乎值得使用 On Error Resume Next / On Error Goto 0 像代码周围的括号;为了安全。
【解决方案4】:

我发现在迭代嵌套对象的函数/子程序中,错误处理可能是 VBA 中的拖累。一个对我来说可以更好地处理复杂迭代的解决方案是在它们自己的函数中分离对象的设置,例如

主要功能/子: 设置 FSOfolder = SetFSOFolder(FSOobject, strFolder)

Private Function SetFSOFolder(FSO as scripting.FileSystemObject, strFolder as string) as Scripting.Folder
    on error resume Next
    set SetFSOFolder = FSO.GetFolder(strFolder)
    on error goto 0
End Function

然后在主函数的下一行:

if (not fsofolder is nothing) then

【讨论】:

    【解决方案5】:

    我同意使用 On Error Resume Next 不是最佳做法,但我的大多数/许多 Access 应用程序对数据完整性中的细微差别(即分析或报告,而不是交易和未经审计)并不过分敏感。出于这个原因,我经常使用 OERN,因为 VBA 对某些您无法完全预料到的情况非常敏感。 1 - 错误是否会导致数据损坏。如果是,处理它。我使用的许多例程只是处理大量记录,并且导入的数据中可能存在尚未修复的错误。通常我有很多转换过程,最终会让系统清理自己的数据。

    2 - 是错误频繁且非关键(即不是关键)。如果是,则为 OERN,否则错误可能无法预测,您最终会崩溃或必须编写一堆 I-T-E 或 Select Case 逻辑来捕获它。

    【讨论】:

      【解决方案6】:

      不要使用On Error Resume Next,而是编写不应崩溃的代码。

      注意:我很小心我的措辞,因为你从不保证代码不会崩溃。但是如果你使用On Error Resume Next,那么你的代码自然流的一部分就是让它崩溃,这是错误的,大错特错。

      【讨论】:

      • VBA 的设计目的不是为了处理没有On Error Resume Next 的所有“危险”情况。 Application.Inputbox 取消按钮呢……所以,一厢情愿。但是,毕竟我同意你的观点:)
      • Try-Catch-FinallyVBA 内不会要求太多!
      • +1 @user1644564 同意您的回答,但创建 On Error Resume Next 是有原因的 - 如果它应该从不被使用,那么为什么将它包含在 @987654328 中@规范?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-01
      • 2011-01-13
      • 1970-01-01
      • 2017-05-09
      • 1970-01-01
      • 2019-09-08
      • 2018-05-15
      相关资源
      最近更新 更多