【问题标题】:Check sheet names to avoid duplicates检查工作表名称以避免重复
【发布时间】:2015-09-19 03:37:56
【问题描述】:

我正在处理一个宏,其中一部分接受用户的输入,询问他/她想要重命名工作表的内容。它工作正常,但如果用户提供的名称已被不同的工作表使用,我会遇到运行时错误。我了解错误发生的原因,但不确定如何警告用户并处理错误。

我的代码如下:-

'Change sheet name

Dim sheetname As String

sheetname = InputBox(Prompt:="Enter Model Code (eg 2SV)", _
      Title:="Model Code", Default:="Model Code here")

wsCopyTo.Name = sheetname

【问题讨论】:

    标签: vba excel error-handling rename


    【解决方案1】:

    最简单的方法是创建一个 Worksheet 变量并将其设置为用户输入的内容(您可能还希望 Trim() 以及删除前导和尾随空格)。

    如果没有,那么名称可以安全使用。如果 Not Is Nothing 则它​​已经存在。

    Dim oWS As Worksheet
    
    On Error Resume Next
    Set oWS = ThisWorkbook.Worksheets(sheetname)
    
    If oWS Is Nothing Then
        ' Safe to use the name
        Debug.Print """" & sheetname & """ is save to use."
        Err.Clear
        wsCopyTo.Name = sheetname
        If Err.Number <> 0 Then
            MsgBox "Cannot use """ & sheetname & """ as worksheet name."
            Err.Clear
        End If
    Else
        Debug.Print """" & sheetname & """ exists already! Cannot use."
        ' worksheet with same name already!
        ' handle it here
    
    End If
    Set oWS = Nothing
    On Error GoTo 0
    

    您也可以将其放入循环中,直到找到未使用的工作表名称。

    【讨论】:

    • 但这不会处理无效字符或长度太长的错误,对吧?
    • 我在尝试更改工作表名称时又添加了 1 项检查。
    【解决方案2】:

    我刚刚写了一篇关于使用 Excel 的本机重命名工作表对话框来执行此操作的帖子。这样您就可以检查重复项、非法字符和过长名称的错误。这是一个添加工作表并调用对话框的例程。如果用户不重命名,则删除新工作表:

    Sub PromptForNewSheetWithName()
    Dim DefaultSheetName As String
    
    ActiveWorkbook.Worksheets.Add
    DefaultSheetName = ActiveSheet.Name
    Application.Dialogs(xlDialogWorkbookName).Show
    If ActiveSheet.Name = DefaultSheetName Then
        MsgBox "You didn't name the new sheet." & vbCrLf & _
               "Processing cancelled", vbExclamation
        Application.DisplayAlerts = False
        ActiveSheet.Delete
        Application.DisplayAlerts = True
    End If
    End Sub
    

    整个帖子在:http://yoursumbuddy.com/prompt-to-name-new-sheet/

    【讨论】:

    • 这很有帮助。有没有办法可以修改它所说的内容?我希望对话框显示“输入型号代码(例如 2SV)”
    • 好问题。唉,没有,至少我知道。
    【解决方案3】:

    有两种方法可以解决这个问题。

    首先捕获错误,检查是否有错误,并提出建议,然后将错误捕获恢复原状

    Dim sheetname As String
    
    sheetname = InputBox(Prompt:="Enter Model Code (eg 2SV)", _
          Title:="Model Code", Default:="Model Code here")
    
    On Error Resume next
    Err.Clear 'ensure previously unhandled errors do not give a false positive on err.number
    wsCopyTo.Name = sheetname
    If Err.Number = ?? then 'go back and ask for another name
    On Error Goto 0
    

    其次,检查当前所有的sheet名称,看看是否匹配

    Dim sheetname As String
    Dim sh 'as Sheet
    
    sheetname = InputBox(Prompt:="Enter Model Code (eg 2SV)", _
          Title:="Model Code", Default:="Model Code here")
    
    for each sh in ActiveWorkbook.Sheets
         If lower(sh.name)=lower(sheetname) then
             'Goback and ask for another name
    Next
    
    wsCopyTo.Name = sheetname
    

    【讨论】:

    • 标记为正确是因为清楚正在做什么以及处理这种情况的多种方法。
    【解决方案4】:

    首先遍历您拥有的名称,并将其名称与用户提供的名称进行比较。如果匹配,请写一条消息说已经使用过。之后退出子。

    For i = 1 To ActiveWorkbook.Worksheets.Count
            If Worksheets(i).Name = sheetname then
                 msgbox "This name is already in use!"
                 exit sub
            End if
    Next
    

    【讨论】:

    • 为了正确捕获错误,我不建议 Err.Clear。请参阅我几周前收到的这份指南:stackoverflow.com/questions/30489035/… 这是投票最高的答案。
    • 我认为你的评论是错误的答案,我使用err.clear 的原因是如果堆栈上存在以前未处理的错误,那么这可能会导致err.number 检查失败,因为该值仅在发生错误或执行 Err.Clear 时更改
    • 就像手套一样!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-14
    • 1970-01-01
    • 1970-01-01
    • 2019-09-28
    • 1970-01-01
    相关资源
    最近更新 更多