测试或检查是否存在纸张

yse*_*yse 102 excel scripting vba

Dim wkbkdestination As Workbook
Dim destsheet As Worksheet

For Each ThisWorkSheet In wkbkorigin.Worksheets 
    'this throws subscript out of range if there is not a sheet in the destination 
    'workbook that has the same name as the current sheet in the origin workbook.
    Set destsheet = wkbkdestination.Worksheets(ThisWorkSheet.Name) 
Next
Run Code Online (Sandbox Code Playgroud)

基本上,我遍历原始工作簿中的所有工作表,然后destsheet在目标工作簿中将其设置为与原始工作簿中当前迭代的工作表相同的工作表.

如何测试该表是否存在?就像是:

If wkbkdestination.Worksheets(ThisWorkSheet.Name) Then 
Run Code Online (Sandbox Code Playgroud)

Tim*_*ams 159

有些人不喜欢这种方法,因为错误处理的"不恰当"使用,但我认为它在VBA中被认为是可接受的......另一种方法是循环所有工作表直到找到匹配.

Function WorksheetExists(shtName As String, Optional wb As Workbook) As Boolean
    Dim sht As Worksheet

    If wb Is Nothing Then Set wb = ThisWorkbook
    On Error Resume Next
    Set sht = wb.Sheets(shtName)
    On Error GoTo 0
    WorksheetExists = Not sht Is Nothing
End Function
Run Code Online (Sandbox Code Playgroud)

  • 人们应该使用`ActiveWorkbook`而不是`ThisWorkbook`.后者指的是包含宏代码的工作簿,它可能与工作簿不同,而不是想要测试的.我猜`ActiveWorkbook`对大多数情况都很有用(但是设计的情况总是可用的). (12认同)
  • 完全适合使用IMO.这是一个陷阱,一个被认为是存在的东西,并没有,并且有悠久的历史 - cf perl strict,STAE等.Upvoted (5认同)
  • 值得注意的是,如果你在个人宏工作簿中运行此代码,请从`如果wb是Nothing然后设置wb = ThisWorkbook`改为`如果wb什么都没有那么设置wb = ActiveWorkbook` (3认同)
  • 如果没有带有该名称的工作表,那么`sht Is Nothing`将是'True`,但是如果*是*具有该名称的工作表,我们想要返回`True`,因此不是.如果你重新排列一下`SheetExists = sht Is Not Nothing`,这会更容易(但无效) (2认同)
  • 这是一种高效的方法(参见我在Rory下面的答案中对基准分数的评论),所以谁关心批评者的想法.注意(截至目前)您的投票数为零. (2认同)
  • @TimWilliams您应该更改为“Dim sht As Object”或将函数命名为“WorksheetExists(…)”并使用“Set sht = wb.Workheets(shtName)”,否则在检查时返回“False”。实际存在的图表。例如。即使名为“Chart1”的图表工作表存在,“SheetExists("Chart1")”也会返回“False”。• `工作表!= 工作表` (2认同)

Ror*_*ory 94

如果您只对工作表感兴趣,可以使用简单的Evaluate调用:

Function WorksheetExists(sName As String) As Boolean
    WorksheetExists = Evaluate("ISREF('" & sName & "'!A1)")
End Function
Run Code Online (Sandbox Code Playgroud)

  • @roryap - 如果你需要运行这500,000次,你需要重新考虑你的整个方法.;) (14认同)
  • @Rory我对Tim Williams的回答进行了一些基准测试.超过500,000个循环,你的花了22秒,蒂姆的花了<1. (12认同)
  • 即使它更慢,它看起来也比公认的答案更简洁。来自我的 +1。 (8认同)
  • @roryap - 然而,使用几种慢速方法将开始堆积秒数.我会说这是非常有价值的信息,因为Excel"应用程序"开始使用各种Range方法等很容易实现秒数. (6认同)
  • @roryap - 这些信息对会话有何价值?我只是声明围绕代码散布低效的方法会使应用程序整体变慢.你测试这500k次是很棒的,我感谢你这样做,22秒不是很好.(我同意你的看法) (4认同)
  • 一个简单的评价。它甚至不需要一个单独的功能 IMO。打的好! (2认同)

fbo*_*tti 41

您无需进行错误处理即可完成此操作.您所要做的就是遍历所有工作表并检查指定的名称是否存在:

For i = 1 To Worksheets.Count
    If Worksheets(i).Name = "MySheet" Then
        exists = True
    End If
Next i

If Not exists Then
    Worksheets.Add.Name = "MySheet"
End If
Run Code Online (Sandbox Code Playgroud)

  • 小心,工作表名称不区分大小写:https://www.howtoexcel.org/how-to-check-if-a-worksheet-exists-using-vba/ (2认同)

Pet*_*ert 21

检查集合成员是一个普遍的问题,这是蒂姆答案的抽象版本:

Function Contains(objCollection As Object, strName as String) As Boolean
    Dim o as Object
    On Error Resume Next
    set o = objCollection(strName)
    Contains = (Err.Number = 0)
    Err.Clear
 End Function

此功能可与像对象的任何集合(使用Shapes,Range,Names,Workbooks,等等).

要检查是否存在纸张,请使用 If Contains(Sheets, "SheetName") ...

  • 这不会捕获集合中的原始类型,因为`Set`关键字会引发错误.我发现,而不是使用`Set`,要求集合的成员的`TypeName`适用于所有的情况下,即'类型名objCollection(则strName)` (5认同)
  • @Peter:最好添加一些东西来清除在funciton终止之前不存在的情况下会出现的错误 - err.clear或On Error Resume Next.否则,在以下情况下可能会无意中触发调用过程中的错误处理.`Sub Test()On Error GoTo errhandler Debug.Print Contains(Workbooks,"SomeBookThatIsNotOpen")errhandler:If Err.Number <> 0 Then Stop End Sub` (2认同)

Sha*_*lon 15

更正: 没有错误处理:

Function CheckIfSheetExists(SheetName As String) As Boolean
      CheckIfSheetExists = False
      For Each WS In Worksheets
        If SheetName = WS.name Then
          CheckIfSheetExists = True
          Exit Function
        End If
      Next WS
End Function
Run Code Online (Sandbox Code Playgroud)


Vir*_*ael 12

如果有人想要避免VBA并测试工作表是否纯粹存在于单元格公式中,则可以使用ISREFINDIRECT函数:

=ISREF(INDIRECT("SheetName!A1"))

TRUE如果工作簿包含一个被调用的工作表SheetName,FALSE则返回此选项.


小智 8

我写了这个:

Function sheetExist(sSheet As String) As Boolean
On Error Resume Next
sheetExist = (ActiveWorkbook.Sheets(sSheet).Index > 0)
End Function
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这一个。请注意,它依赖于以下事实:sheetExist 的默认值为 False,因为它是一个布尔函数。如果工作表不存在,赋值语句实际上不会将 False 值分配给sheetExist,它只是出错并保留默认值。如果您愿意,您可以相信分配给布尔变量的任何非零值都会给出 True 结果并忽略 &gt; 0 比较,如下所示:`sheetExist = ActiveWorkbook.Sheets(sSheet).Index` (2认同)

小智 5

我的解决方案看起来很像Tims,但也适用于非工作表表 - 图表

Public Function SheetExists(strSheetName As String, Optional wbWorkbook As Workbook) As Boolean
    If wbWorkbook Is Nothing Then Set wbWorkbook = ActiveWorkbook 'or ThisWorkbook - whichever appropriate
    Dim obj As Object
    On Error GoTo HandleError
    Set obj = wbWorkbook.Sheets(strSheetName)
    SheetExists = True
    Exit Function
HandleError:
    SheetExists = False
End Function
Run Code Online (Sandbox Code Playgroud)

.


ash*_*awg 5

紧凑的wsExists功能依赖错误处理!)

这是一个简短而简单的函数,它不依赖于错误处理来确定工作表是否存在(并且被正确声明为在任何情况下都可以工作!)

Function wsExists(wsName As String) As Boolean
    Dim ws: For Each ws In Sheets
    wsExists = (wsName = ws.Name): If wsExists Then Exit Function
    Next ws
End Function
Run Code Online (Sandbox Code Playgroud)

示例用法:

下面的示例添加一个名为 的新工作表myNewSheet(如果它不存在):

If Not wsExists("myNewSheet") Then Sheets.Add.Name = "myNewSheet"
Run Code Online (Sandbox Code Playgroud)

更多信息: