VBA Excel 简单的错误处理

VBA Excel simple Error Handling

我尽可能多地上网查看(Microsoft 支持网站除外,该网站因某种原因在工作中被屏蔽)。我试图简单地跳过一个错误。我在此处编写的代码已简化,但应该以相同的方式工作。

我的代码应该做什么: 我的一个潜艇在循环中创建形状并命名它们(btn_1、btn_2 等)。但在创建它们之前,它会调用一个尝试删除它们的子程序,以免创建重复项。此子循环遍历(btn_1、btn_2 等)并使用以下方法删除形状:

for i = 1 to (a certain number)
    Set shp = f_overview.Shapes("btn_" & i)
    shp.delete
next

当然,恰好形状不能删除,因为它根本不存在。我发现大多数时候,推荐的修复方法是在设置形状之前添加(下一个错误恢复),因为我收到一条错误消息说它不存在。我已经在循环内部、循环之前等尝试过它,像这样:

for i = 1 to (a certain number)
    On Error Resume Next
    Set shp = f_overview.Shapes("btn_" & i)
    shp.delete
next

据我所知,如果形状不存在,它应该直接循环,但无论我接下来是否添加 On error resume,我仍然会收到相同的错误!我做错了什么?

编辑:形状确实存在时没有错误。

尝试:

On Error Resume Next

for i = 1 to (a certain number)
    Set shp = f_overview.Shapes("btn_" & i)
    if err<>0 then err.clear else shp.delete
next

on Error Goto 0

听起来您设置的错误捕获选项有误。在 VBA 编辑器中,Select Tools -> Options。在打开的 window 中,select General tab,然后选择 Break on Unhandled Errors 单选按钮。这应该允许 Excel 正确处理 On Error Resume Next 命令。

我怀疑你 Break on All Errors selected.

与其尝试盲目删除形状并跳过错误,不如 运行 通过已知形状列表并删除它们。那么您就不必担心On Error Resume Next 经常 最终被滥用。

Sub Test(TheSheet As Worksheet)

Dim Shp as Shape

For Each Shp in TheSheet.Shapes
  If left(Shp.Name, 4) = "btn_" Then
    Shp.Delete
  End if
Next

End Sub

如果要删除所有形状,请删除 If 语句。如果要删除多个不同名称的形状,请适当修改 If 语句。

I have found that most of the time, the reccomended fix is to add (on error resume next) before setting the shape, as I get an error saying it does not exist.

不!

处理运行时间错误的推荐方法是而不是将它们推到地毯下并继续执行,就好像什么都没发生 - 这正是 On Error Resume Next 所做的。

避免 运行时间错误的最简单方法是检查错误条件,并避免执行导致 100% 失败率的代码,例如尝试 运行 对象引用上的方法 Nothing:

For i = 1 To (a certain number)
    Set shp = f_overview.Shapes("btn_" & i)
    If Not shp Is Nothing Then shp.Delete
Next

在您无法检查错误条件并且必须处理错误的情况下,推荐的方法是处理它们:

Private Sub DoSomething()
    On Error GoTo CleanFail

    '...code...

CleanExit:
    'cleanup code here
    Exit Sub

CleanFail:
    If Err.Number = 9 Then 'subscript out of range
        Err.Clear
        Resume Next
    Else
        MsgBox Err.Description
        Resume CleanExit
    End If
End Sub

使用 OERNOn Error Resume Next)没有任何错误,前提是您了解自己在做什么以及进展如何影响你的代码。

在你的情况下,使用 OERN 是完全正常的

Dim shp As Shape

For i = 1 To (a certain number)
    On Error Resume Next
    Set shp = f_overview.Shapes("btn_" & i)
    shp.Delete
    On Error GoTo 0
Next

同时确保你不会做类似

的事情
On Error Resume Next
<Your Entire Procedure>
On Error GoTo 0

这将抑制所有错误。使用正确的错误处理,如 Matt

所示

编辑:

这是另一个关于如何使用 OERN 的漂亮示例。此函数检查特定作品sheet 是否存在。

Function DoesWSExist(wsName As String) As Boolean
    Dim ws As Worksheet

    On Error Resume Next
    Set ws = ThisWorkbook.Sheets(wsName)
    On Error GoTo 0

    If Not ws Is Nothing Then DoesWSExist = True
End Function

如果您愿意,还可以遍历所有 sheet 来检查 sheet 是否存在!