シートが存在するかどうかをテストまたは確認する


115
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

基本的に、元のワークブックのすべてのシートをループしてから設定します destsheet現在反復されているシートと同じ名前のシートを、ターゲットのワークブックにします。

そのシートが存在するかどうかをどのようにテストできますか?何かのようなもの:

If wkbkdestination.Worksheets(ThisWorkSheet.Name) Then 

回答:


173

一部の人々は、エラー処理の「不適切な」使用のためにこのアプローチを嫌っていますが、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

5
完全に適切なIMOの使用。これは、既存のように仮定していませんし、長い歴史を持っていているもののための罠だ- CF perlの厳格な、STAEなどUpvoted

13
おそらくのActiveWorkbook代わりに使用する必要がありThisWorkbookます。後者は、マクロコードを含むワークブックを指します。これは、テストしたいワークブックとは異なる場合があります。私ActiveWorkbookはほとんどの場合に役立つと思います(ただし、人為的な状況はいつでも利用できます)。
sancho.s ReinstateMonicaCellio 2014

3
sht Is NothingなりますTrueがその名前のシートませんが、我々は返すようにしたい場合Trueがある場合であるので、ない、その名前を持つシート。少し並べ替えると少し簡単になります(ただし有効ではありません)SheetExists = sht Is Not Nothing
Tim Williams

3
ノートに良いから、あなたの個人用マクロブックにこのコードを実行する場合は、変更することIf wb Is Nothing Then Set wb = ThisWorkbookIf wb Is Nothing Then Set wb = ActiveWorkbook
ヘンリック・K

2
これは非常に効率的なアプローチです(下のRoryの回答にあるベンチマークに関する私のコメントを参照)。(現時点では)反対票がないことに注意してください。
rory.ap 2016年

107

ワークシートのみに特に関心がある場合は、単純なEvaluate呼び出しを使用できます。

Function WorksheetExists(sName As String) As Boolean
    WorksheetExists = Evaluate("ISREF('" & sName & "'!A1)")
End Function

14
@ロリー私はこれとティム・ウィリアムズの答えに対していくつかのベンチマークテストを行いました。500,000以上のループで、あなたのループは22秒かかり、ティムのループは<1でした。
rory.ap 2016年

17
@roryap-これを50万回実行する必要がある場合は、アプローチ全体を再考する必要があります。;)
Rory

9
@roryap-ただし、いくつかの遅いメソッドを使用すると、数秒で蓄積が始まります。私は、など、さまざまな範囲の方法でかなり簡単に秒を稼がを開始し、「アプリケーション」Excelなど、これは非常に貴重な情報であると言うだろう
tedcurrent

4
@roryap-その情報は、会話にとってどのように価値がありますか?私は単に、コードの周りに非効率的なメソッドを散在させると、アプリケーション全体が遅くなると述べています。これを50万回テストするのは素晴らしいです。それを実行してくれてありがとう、22秒はすばらしいとは言えません。(同意します)
2016年

6
遅くても、受け入れられた答えよりもはるかにクリーンなソリューションのように見えます。私からの+1。
Sascha L.

49

これを実行するためにエラー処理は必要ありません。あなたがしなければならないのは、すべてのワークシートを反復処理し、指定された名前が存在するかどうかを確認することだけです。

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

21

コレクションのメンバーをチェックすることは一般的な問題なので、ここにティムの答えの抽象化されたバージョンがあります:

関数Contains(objCollection As Object、strName as String)As Boolean
    オブジェクトを暗くする
    エラー時に再開
    set o = objCollection(strName)
    含む=(エラー番号= 0)
    エラークリア
 終了機能

この関数は、オブジェクト(のような任意のコレクションで使用することができShapesRangeNamesWorkbooks、など)。

シートの存在を確認するには、 If Contains(Sheets, "SheetName") ...


5
Setキーワードによってエラーが発生するため、これはコレクションのプリミティブ型をキャッチしません。私が使用するのではなく、それを見つけSetを求め、TypeNameすべての場合、すなわちの収集作品のメンバーのTypeName objCollection(strName)
citizenkong

2
@Peter:関数が終了する前に存在しない場合に発生するエラーをクリアするために何かを追加することをお勧めします-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
jeffreyweir、2015年

16

修正: エラー処理なし:

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

14

誰もがVBAを避け、純粋にセル数式内にワークシートが存在するかどうかをテストする場合は、ISREFおよびINDIRECT関数を使用して可能です。

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

これは戻りますTRUE、ブックと呼ばれるシートが含まれている場合SheetNameFALSEそうでありませんの。


12

私はこれを書いた:

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

1
素晴らしい機能!高速であるだけでなく、最も簡潔でもあります。
ChrisB

これは、質問に最も対応する答えだと思います
Juan Joya

私はこれが好きです。これはブール関数であるため、sheetExistのデフォルト値がFalseであることに依存していることに注意してください。割り当てステートメントは、シートが存在しない場合、実際にはfalse値をsheetExistに割り当てません。エラーが発生し、デフォルト値がそのまま残ります。あなたがしたい場合は、ブール変数に代入ゼロ以外の値がTrueの結果を与えるという事実に頼ることができますので、同様に、> 0の比較を省略: sheetExist = ActiveWorkbook.Sheets(sSheet).Index
oddacorn

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


3

テストを関数に入れると、それを再利用できるようになり、コードが読みやすくなります。

「On Error Resume Next」はコードの他の部分と競合する可能性があるため、使用しないでください。

Sub DoesTheSheetExists()
    If SheetExist("SheetName") Then
        Debug.Print "The Sheet Exists"
    Else
        Debug.Print "The Sheet Does NOT Exists"
    End If
End Sub

Function SheetExist(strSheetName As String) As Boolean
    Dim i As Integer

    For i = 1 To Worksheets.Count
        If Worksheets(i).Name = strSheetName Then
            SheetExist = True
            Exit Function
        End If
    Next i
End Function

3

何年も遅れたが、私はこれを行う必要があり、投稿されたソリューションのどれも好きではなかった...それで、私は1つを作成した。

Evaluate("IsError(" & vSheetName & "!1:1)")

Sheetが存在しない場合はTRUEを返します。シートが存在する場合はFALSE。「1:1」は任意の範囲に置き換えることができますが、エラー(#N / Aなど)が含まれている場合はTrueを返す単一のセルを使用しないことをお勧めします。


3

コンパクトな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

使用例:

次の例では、という名前の新しいワークシートmyNewSheetがまだ存在しない場合、追加します。

If Not wsExists("myNewSheet") Then Sheets.Add.Name = "myNewSheet"

詳しくは:


2

小さなループを使用して、名前付きワークシートが存在するかどうかを判断しないのはなぜですか?現在開いているワークブックで「Sheet1」という名前のワークシートを探していたとしましょう。

Dim wb as Workbook
Dim ws as Worksheet

Set wb = ActiveWorkbook

For Each ws in wb.Worksheets

    if ws.Name = "Sheet1" then
        'Do something here
    End if

Next

2

あなたはのファンならWorksheetFunction.またはあなたは、これは良い解決策、その作品で英語以外のエクセルで英語以外の国からの仕事します:

WorksheetFunction.IsErr(Evaluate("'" & wsName & "'!A1"))

または次のような関数で:

Function WorksheetExists(sName As String) As Boolean
    WorksheetExists = Not WorksheetFunction.IsErr(Evaluate("'" & sName & "'!A1"))
End Function

1
Public Function WorkSheetExists(ByVal strName As String) As Boolean
   On Error Resume Next
   WorkSheetExists = Not Worksheets(strName) Is Nothing
End Function

sub test_sheet()

 If Not WorkSheetExists("SheetName") Then
 MsgBox "Not available"
Else MsgBox "Available"
End If

End Sub

1
    For Each Sheet In Worksheets
    If UCase(Sheet.Name) = "TEMP" Then
    'Your Code when the match is True
        Application.DisplayAlerts = False
        Sheet.Delete
        Application.DisplayAlerts = True
    '-----------------------------------
    End If
Next Sheet

1

「データ」を、テストしているシート名に変更します...

On Error Resume Next 

Set DataSheet = Sheets("Data")

If DataSheet Is Nothing Then

     Sheets.Add(after:=ActiveSheet).Name = "Data"
     ''or whatever alternate code you want to execute''
End If

On Error GoTo 0

1

上記の関数が機能することは間違いありませんが、次のコードでかなりうまくいきました。

Sub Sheet_exist ()
On Error Resume Next
If Sheets("" & Range("Sheet_Name") & "") Is Nothing Then
    MsgBox "doesnt exist"
Else
    MsgBox "exist"
End if
End sub

注:Sheets_Nameここでは、ユーザーに名前の入力を求めています。そのため、これは同じではない場合があります。


0

私は別のことをしました:シートが存在する場合にのみシートを削除します-シートが存在しない場合でもエラーになりません:

Excel.DisplayAlerts = False 
Dim WS
For Each WS In Excel.Worksheets
    If WS.name = "Sheet2" Then
        Excel.sheets("Sheet2").Delete
        Exit For
    End If
Next
Excel.DisplayAlerts = True

0

簡単な方法を考え出しましたが、そのための新しいサブを作成していません。代わりに、私が取り組んでいたサブ内で「チェックを実行」しました。私たちが探しているシート名が「Sheet_Exist」であり、見つかった場合にそれをアクティブ化したいと仮定します。

Dim SheetCounter As Integer

SheetCounter = 1

Do Until Sheets(SheetCounter).Name = "Sheet_Exist" Or SheetCounter = Sheets.Count + 1
 SheetCounter = SheetCounter +1
Loop
If SheetCounter < Sheets.Count + 1 Then
 Sheets("Sheet_Exist").Activate
Else
 MsgBox("Worksheet ""Sheet_Exist"" was NOT found")
End If

シートが存在しない場合のポップアップも追加しました。


0

私はそれが古い記事であることを知っていますが、これは高速な別の簡単な解決策です。

Public Function worksheetExists(ByVal wb As Workbook, ByVal sheetNameStr As String) As Boolean

On Error Resume Next
worksheetExists = (wb.Worksheets(sheetNameStr).Name <> "")
Err.Clear: On Error GoTo 0

End Function


-4

実際には、シートが存在するかどうかを確認してからいくつかの命令を実行する簡単な方法がありました。

私の場合、シートを削除してから同じ名前で同じシートを再作成したかったのですが、すでに削除されているためプログラムがシートを削除できなかった場合、コードが中断されました。

Sub Foo ()

    Application.DisplayAlerts = False

    On Error GoTo instructions
    Sheets("NAME OF THE SHEET").Delete

    instructions:

    Sheets.Add After:=Sheets(Sheets.Count)
    ActiveSheet.Name = "NAME OF THE SHEET"

End Sub

この回答の問題は、シートが実際に存在していたと判断すると削除され、存在しないことです。これが関数として記述された場合、SheetExistsAfterDeletionのような名前が付けられ、常にFALSEを返します。
ChrisB
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.