【问题标题】:Why does error handler not handle a second error?为什么错误处理程序不处理第二个错误?
【发布时间】:2019-09-12 06:44:28
【问题描述】:

我正在尝试复制给定的工作表并重命名该副本 sheet2,但如果 sheet2 存在,则将其重命名为 sheet3,如果 sheet3 存在,则将其重命名为 sheet4 等。

我正在尝试使用带有错误处理的无限 while 循环(即,如果它尝试重命名工作表并且存在相同的工作表,它会处理错误并将后缀增加 1,但如果没有发生错误,它会退出循环)。

Sub Clone()

    Application.ScreenUpdating = False

    Dim ParamsToBeCloned As String
    Dim wsNumber As Long
    Dim suffix As Long

    ParamsToBeCloned = Sheets("Interface").Range("ParamsToBeCloned")

    wsNumber = Sheets(ParamsToBeCloned).index
    Sheets(ParamsToBeCloned).Copy after:=Sheets(wsNumber)

    suffix = 2
    Do While True
        On Error GoTo sheetExists
        ActiveSheet.Name = ParamsToBeCloned & suffix
        Exit Do
sheetExists:
        suffix = suffix + 1
    Loop

    Sheets("Interface").Select

    Application.ScreenUpdating = True

End Sub

这在 Params2 存在以产生 Params3 时有效,但如果 Params2 和 Params3 都存在,则会抛出错误

“该名称已被占用。请尝试其他名称。”

我不明白为什么当 Params2 存在时它能够生成 Params3,但是当 Params2 和 Params3 都存在时它不能生成 Params4。

也就是为什么第二次没有处理错误?

【问题讨论】:

    标签: excel vba error-handling


    【解决方案1】:

    只是使用 On Error 的替代方法:

    For x = 2 To 1000
        If Application.Evaluate("ISREF(" & ParamsToBeCloned & x & "!A1)") = False Then
            ActiveSheet.Name = ParamsToBeCloned & x
            Exit For
        End If
    Next x
    

    要检查工作表是否存在,我们可以尝试查看 ISREF 是否返回 TRUEFALSE。在FALSE,您可以为您的工作表命名。


    根据@Peh 他的评论,您可能需要先检查ParamsToBeClonedx 是否是valid 工作表名称。

    【讨论】:

    • 请注意:虽然这会检查工作表是否存在,但不会检查 ParamsToBeCloned & x 是有效名称还是由于长度或字符而无效。所以它仍然可能需要适当的错误处理,因为名称是从单元格中检索的(您不能信任的用户输入)。
    • @Pᴇʜ,确实取决于ParamsToBeCloned 变量的验证。
    • 是的,没错。但是错误处理可能比验证字符串是否是工作表的有效名称更容易实现:) 实际上我无法想象更简单的方法。
    • 你可能是对的,但是我总是会开始寻找规避on error 的需求:)。我会保留答案,以防人们在使用有效变量时发现它很有用。
    • 当然,我不是故意抹黑你的回答(你得到了我的投票)。
    【解决方案2】:

    您需要清除错误以触发我认为的另一个错误。尝试在suffix = suffix + 1 之后添加On Error Goto 0。这可能也有帮助VBA Error Handling – A Complete Guide

    另请注意,如果无法重命名活动工作表,此循环将永远运行。例如,如果ParamsToBeCloned 包含不允许的字符或长度超过 32 个字符(Excel 对工作表名称的限制),则可能会发生这种情况。因此,您可能希望将其更改为最大为 1000 的 For 循环。

    For suffix = 2 To 1000
        On Error Resume Next
        ActiveSheet.Name = ParamsToBeCloned & suffix
        If Err.Number = 0 Then 'no error so successfully renamed
            On Error GoTo 0
            Exit For
        End If
        On Error GoTo 0
        If suffix = 1000 Then MsgBox "Maximum reached could not rename sheet"
    Next suffix
    

    【讨论】:

    • 谢谢佩。我确实考虑过像您在这里所做的那样的 for 循环,但认为另一个更优雅。但我确实同意你的观点,所以我会选择 for 循环选项。干杯
    • 顺便说一句。 On Error GoTo 0 不起作用,但 On Error GoTo -1。在此处发布以防万一这对其他人有帮助。再次感谢您的帮助。干杯
    • @brb Strange 实际上两者都应该工作。如果您使用On Error GoTo -1,请确保您在循环之后有一个On Error GoTo 0。或者如果你的循环后面有异常,它会跳回循环。
    • Hrmm.... 让我再试一次。我没有复制所有错误处理,因为我得到了以下工作。所以,也许我的建议很糟糕......如果是这样,对不起! For suffix = 2 To 100 On Error GoTo sheetExists ActiveSheet.Name = ParamsToBeCloned & suffix Exit For sheetExists: On Error GoTo -1 Next suffix
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-29
    相关资源
    最近更新 更多