【问题标题】:Excel VBA check if a sheet already existsExcel VBA 检查工作表是否已存在
【发布时间】:2020-07-28 08:58:48
【问题描述】:

我在 Excel VBA 中有一些代码,它的作用是每当用户打开特定工作簿时,它会从最后一张工作表中复制内容,然后将这个新工作表放在最后,然后给出一个新工作表通过输入日期格式为工作表命名。问题是,如果由于某种原因您需要在同一天再次打开此工作簿,则会出现错误,因为工作表的名称已被占用。

我正在尝试找到一个解决方案,如果名称已经存在,则不要添加新工作表。可能我的代码的某些部分是正确的,但我猜代码行的顺序可能是导致它出错的原因。

Sub Auto()
Sheets(Sheets.Count).Select
Sheets(Sheets.Count).Copy After:=Sheets(Sheets.Count)
Sheets(Sheets.Count).Select
For i = 1 To Sheets.Count
    If Sheets(i).Name = UCase(Format(Now, "DDMMM")) Then
    exists = True
    End If

Next i
If Not exists Then
    Sheets(Sheets.Count).Name = UCase(Format(Now, "DDMMM"))
End If

Range("A3:P3").Select
ActiveCell.FormulaR1C1 = Format(Now, "medium date")

End Sub

我刚刚添加了循环条件,但此代码有两处错误。 if 将继续查找工作簿中的每张纸,因此如果您有 200 张纸,则可能需要一些时间才能退出循环。另一个是,每当您添加一个作为另一个副本的工作表时,Excel 都会将相应副本(Sheet (2))添加到工作表的名称中,因此循环不会执行任何操作,因为它永远不会找到相同的名称。

因此,如果您有更好的方法来检查工作表名称是否已存在,我将很高兴学习。

谢谢

【问题讨论】:

  • 这能回答你的问题吗? Test or check if sheet exists
  • 我已经阅读了那里的一些建议,我可以看到名称是为某些东西预定义的。对于工作表的名称,我使用的是将名称格式化为日期。我已经尝试了一些解决方案,甚至是循环,但循环会继续,它不会找到相同的名称,因为首先你需要行代码Sheets(Sheets.Count).Name = UCase(Format(Now, "DDMMM")),但是如果你尝试在循环之前运行它,它会给你一个运行错误。
  • 第一次循环并查看工作表是否存在,或使用第一条评论中提供的链接中的方法。如果工作表存在,Exit Sub。否则,进行复制和重命名。

标签: excel


【解决方案1】:

您可能喜欢使用以下功能。你给它一个工作表名称,它会返回一个同名的工作表对象,要么是已经存在的,要么是刚刚创建的。

Function GetSheet(SheetName As String) As Worksheet

    Dim Fun         As Worksheet            ' Function return object
    
    On Error Resume Next
    Set Fun = Worksheets(SheetName)
    ' if the sheet doesn't exist an error will occur here
    If Err Then
        Set Fun = Worksheets.Add(After:=Sheets(Sheets.Count))
        Fun.Name = SheetName
    End If
    Set GetSheet = Fun
End Function

您可以使用如下所示的语法从您的 Main 过程中调用该函数。

Sub Main()
    Dim Ws          As Worksheet
    Dim SheetName   As String
    
    ' Now() includes the time
    SheetName = UCase(Format(Date, "ddmmm"))
    Set Ws = GetSheet(SheetName)
    
    With Ws
        Debug.Print .Name
        .Cells(3, "A").Value = Format(Date, "medium date")
        .Range("A3:P3").Select
    End With
End Sub

当然,当此代码集成到您的项目中时,该功能不太可能位于最前面。它将位于底部,位于 main 下方,或者,如果您的项目中有很多功能,则位于专门用于管理功能的单独模块中。

【讨论】:

  • 是的!这正是我所缺少的,因为我没有直接使用 if 循环得到错误,它没有去搜索名称,但是现在使用函数如果工作表已经有一个具有该名称的工作表,它将接下来继续。虽然我仍在试图弄清楚 debug.print.name 是什么,因为我现在看不到它有什么用处。
  • 哈哈,没用的。这只是证明该函数返回了一些东西,在立即窗口中可见。删除线。顺便说一句,创建工作表时,它将是 ActiveSheet。如果它已经存在,它可能不存在。如果您希望该工作表处于活动状态,请使用Ws.Activate,或者在函数开始时将 ActiveSheet 分配给对象变量并在最后再次激活该工作表。避免选择代码中的任何内容。 .Range("A3:P3").Select 供用户查看。 Excel 和 VBA 知道它的存在,您可以直接访问该范围,如上面的行所示。
  • 谢谢,是的,那行工作正常问题是Set Fun = Worksheets.Add(After:=Sheets(Sheets.Count)) 我想复制活动工作表的内容相同的信息。我尝试将其更改为Set Fun = Worksheets.Copy(After:=Sheets(Sheets.Count)),但现在它告诉我它需要一个函数或一个变量。我什至尝试更改工作表的类,但我得到了同样的错误。我什至尝试了以下代码If Err Then Sheets(Sheets.Count).Copy Set Fun = Worksheets.Add(After:=Sheets(Sheets.Count)) Fun.Name = SheetName End If Set GetSheet = Fun End Function
  • 不清楚。您想以 29JUL 之类的名称创建 ActiveSheet 的副本吗?如果是这样,如果工作表已经存在应该怎么办?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-15
  • 2011-10-13
  • 1970-01-01
  • 2018-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多