【问题标题】:If sheet exist, don't add another one如果工作表存在,请不要添加另一个工作表
【发布时间】:2023-03-31 20:06:01
【问题描述】:

如果工作表“数据”不存在,则代码工作正常,如果确实存在,但我收到错误“名称已存在,请尝试其他名称”。我只是用On Error GoTo ErrorHandler 解决了这个问题,但是问题是在代码运行并且宏触发错误处理程序 msgbox 之后,它仍然会创建一个新工作表(名称为'Sheet1,2,3,... ')。

片段:

Sub AddWorkSheet()
    Dim wb As Workbook, shtDest As Worksheet
    On Error GoTo ErrorHandler
    Sheets.Add.Name = ("Data")
    Set shtDest = Sheets("Data")

ErrorHandler:
    MsgBox ("Something went wrong."), vbCritical

End Sub

如果工作表“数据”已经存在,我希望代码只返回消息框而不创建任何其他工作表。

【问题讨论】:

标签: excel vba


【解决方案1】:

在添加工作表之前,检查它是否存在:

Function ShtExist(ShtName As String) As Boolean
On Error Resume Next
    ShtExist = Len(ThisWorkbook.Sheets(ShtName).Name) > 0
On Error GoTo 0
End Function

Sub AddWorkSheet()

    Dim wb As Workbook, shtDest As Worksheet
    If ShtExist("Data") Then
    MsgBox ("Something went wrong."), vbCritical
    Else
    Sheets.Add.Name = ("Data")
    Set shtDest = Sheets("Data")
    End If

End Sub

【讨论】:

    【解决方案2】:

    当您尝试将不存在的工作表分配给变量时,VBA 将返回错误 9。从我的 POV 来看,我认为捕获该错误然后在需要时创建工作表很有用。

    所以我会使用:

    Sub AddWorkSheet()
    Dim wb As Workbook, shtDest As Worksheet
    
    On Error GoTo ErrorHandler
    Set shtDest = Sheets("Data")
    
    
    '<--rest of your code-->
    '
    '
    '
    '
    '
    '
    ''<--rest of your code-->
    
    Set shtDest = Nothing
    Set wb = Nothing
    
    Exit Sub
    
    
    ErrorHandler:
    If Err.Number = 9 Then
        'must create worksheet DATA
        Sheets.Add.Name = ("Data")
        Set shtDest = Sheets("Data")
        Resume Next
    Else
        'different error. MSgbox with new error
        MsgBox Err.Description, vbCritical, Err.Number
        Stop
    End If
    End Sub
    

    请注意,在 ErrorHanlder 部分之前,我添加了 Exit Sub 以避免每次子运行时都执行这部分代码。

    【讨论】:

    • 不幸的是,这似乎不起作用。我仍然得到同样的错误(1004,通过错误处理程序中的 else 函数),但之后又创建了另一个编号的工作表。
    • 您在MsgBox Err.Description, vbCritical, Err.Number 行中收到错误1004?
    【解决方案3】:

    编辑:此答案的先前版本产生了错误的结果,详细信息在 cmets 中。)

    这应该可行。注意On Error Resume NextOn Error GoTo 0 结合使用,而不是On Error GoTo ErrorHandler。 (GoTo 语句通常与 so-called "spaghetti code" 相关联,因此尽可能避免使用它们可能是一个好习惯。)

    Sub AddWorkSheet()
        Dim wb As Workbook, ws As Worksheet
        On Error Resume Next
        Set ws = Worksheets("Data")
        If Err.Number <> 9 Then ' 9 means subscript out of range
            MsgBox ("Sheet already exists."), vbCritical
        Else
            Sheets.Add After:=Worksheets(Worksheets.Count)
            Sheets(Worksheets.Count).Name = "data"
        End If
        On Error GoTo 0
    End Sub
    

    在您的原始代码中,您可以在错误处理程序之前添加一个Exit Sub 语句;没有它ErrorHandler 将始终被调用。 (您可能想看看documentation。)。

    【讨论】:

    • 我几乎不推荐阅读:What's the deference between “end” and “exit sub” in VBA?End 会杀死你的整个 VBA 执行。 • 即使工作表data 存在,您的代码仍会添加工作表。
    • 确实,我太草率了,我已经进行了相应的编辑。感谢您的指正。 (至于EndExit Sub,我完全意识到差异,这在编辑后无关紧要,但显然应该根据上下文做出选择。)
    • 如果存在一个名为Data 的图表表,它将失败,因为您只检查现有的工作表。请注意Sheets &lt;&gt; WorksheetsSheets 可以包含所有类型的工作表,例如 ChartsWorksheets 等。
    • 再次感谢,好点子。一直在学习。我将暂时保留该帖子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-26
    • 1970-01-01
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多