ワークシートの削除

にメンテナンス済み

VBA でワークシートを削除するには、Worksheet.Delete メソッドを使います。

ただし、そのまま実行すると確認ダイアログが表示されたり、シートが存在しないとエラーになったりと、実務ではいくつか気をつけるポイントがあります。

本記事では、基本コードから、確認メッセージの非表示、存在確認、複数シートの一括削除、削除できないときの対処法までを解説します。

ワークシートを削除する基本コード

ワークシートを削除する基本コード
Private Sub DeleteSheet()
  ThisWorkbook.Worksheets("Sheet1").Delete
End Sub

このコードは、このマクロを記述したブックの “Sheet1” という名前のワークシートを削除します。

Worksheets("Sheet1") のようにブックを指定せずに書くと、アクティブなブックが対象になります。複数のブックを開いているときに意図しないブックのシートを削除しないよう、ThisWorkbook(マクロを記述したブック)や ActiveWorkbook を明示するのがおすすめです。

Worksheets と Sheets の違い

Worksheetsはワークシートだけのコレクション、Sheetsはグラフシートなども含むコレクションです。ワークシートだけを扱うならWorksheetsを使えば十分です。

確認メッセージを表示せずに削除する

内容の入っているシートを削除すると、「選択したシートに、データが存在する可能性があります」という趣旨の確認ダイアログが表示され、マクロはユーザーの操作を待って止まってしまいます。

Application.DisplayAlerts = False を指定すると、確認ダイアログを表示せずに削除できます(この場合、確認メッセージの既定の選択肢である「削除」が選ばれたものとして処理されます)。

メッセージを表示せずにワークシートを削除
Private Sub DeleteSheetWithoutAlert()
    Application.DisplayAlerts = False
    ThisWorkbook.Worksheets("Sheet1").Delete
    Application.DisplayAlerts = True
End Sub
注意

ワークシートの削除は元に戻せません(Ctrl + Z で取り消せません)。また、DisplayAlertsをFalseにしたままマクロが終了すると、他の操作でも警告が表示されなくなります。必ず削除後にTrueへ戻してください。

特定のワークシートが存在する場合だけ削除する

存在しない名前のシートを指定して Delete を実行すると、実行時エラー 9(インデックスが有効範囲にありません)が発生します。シートの存在確認を関数にしておくと、削除前のチェックに使い回せます。

シートの存在確認を行ってから削除
Private Function SheetExists(ByVal sheetName As String) As Boolean
    Dim ws As Worksheet
    For Each ws In ThisWorkbook.Worksheets
        If StrComp(ws.Name, sheetName, vbTextCompare) = 0 Then
            SheetExists = True
            Exit Function
        End If
    Next ws
End Function

Private Sub DeleteSheetIfExists(ByVal sheetName As String)
    If Not SheetExists(sheetName) Then
        MsgBox "シート「" & sheetName & "」は存在しません。"
        Exit Sub
    End If

    Application.DisplayAlerts = False
    ThisWorkbook.Worksheets(sheetName).Delete
    Application.DisplayAlerts = True
End Sub

On Error Resume Next で Set ws = Worksheets(sheetName) を試す方法もありますが、エラーを握りつぶすコードは意図しないエラーまで見逃しやすいため、ここではループで確認する方法を採用しています。

複数のワークシートを一度に削除する

削除したいシート名を配列で渡し、ループで削除します。

複数ワークシートを削除する
Private Sub DeleteMultipleSheets(ByVal sheetNames As Variant)
    Dim sheetName As Variant

    On Error GoTo Cleanup
    Application.DisplayAlerts = False
    For Each sheetName In sheetNames
        If SheetExists(CStr(sheetName)) Then
            ThisWorkbook.Worksheets(CStr(sheetName)).Delete
        End If
    Next sheetName

Cleanup:
    Application.DisplayAlerts = True
    If Err.Number <> 0 Then MsgBox Err.Description
End Sub

Sub ExecuteDeleteMultipleSheets()
    DeleteMultipleSheets Array("Sheet1", "Sheet2", "Sheet3")
End Sub

存在しないシートは SheetExists でスキップされるため、一部のシートがなくても最後まで処理できます。

Array を直接 Worksheets に渡す方法

ThisWorkbook.Worksheets(Array("Sheet1", "Sheet2")).Deleteのように、シート名の配列を渡して一括削除することもできます。ただし、1つでも存在しない名前があるとエラーになります。

すべてのシートを削除することはできない

ブックには、最低でも1枚の表示されているシートが必要です。すべてのシートを削除しようとすると、最後の1枚でエラーになります。シートを入れ替えたい場合は、先に新しいシートを追加してから古いシートを削除してください。

エラーハンドリング

削除に失敗する可能性がある処理では、On Error GoTo でエラー処理を書いておきましょう。特に DisplayAlerts を False にしている間にエラーが起きると、True に戻る前に処理が抜けてしまうため、エラー処理の中でも必ず True に戻します。

エラーハンドリングのコード例
Private Sub DeleteSheetWithErrorHandling(ByVal sheetName As String)
    On Error GoTo ErrorHandler

    Application.DisplayAlerts = False
    ThisWorkbook.Worksheets(sheetName).Delete
    Application.DisplayAlerts = True
    Exit Sub

ErrorHandler:
    Application.DisplayAlerts = True
    MsgBox "シートの削除中にエラーが発生しました: " & Err.Description
End Sub

削除前に確認メッセージを出す

誤削除を防ぎたい場合は、自分で確認メッセージを表示します。

確認メッセージ付きのコード例
Private Sub DeleteSheetWithConfirmation(ByVal sheetName As String)
    If Not SheetExists(sheetName) Then
        MsgBox "シート「" & sheetName & "」は存在しません。"
        Exit Sub
    End If

    If MsgBox("シート「" & sheetName & "」を削除しますか?", vbYesNo + vbQuestion, "削除の確認") = vbYes Then
        Application.DisplayAlerts = False
        ThisWorkbook.Worksheets(sheetName).Delete
        Application.DisplayAlerts = True
    End If
End Sub

ワークシートを削除できないときの原因と対処法

ブック構成が保護されている場合

シートの追加・削除は「ブック構成の保護」が有効だとできません。その場合は保護を解除してから削除します。

Private Sub UnprotectWorkbookAndDelete(ByVal sheetName As String)
    ThisWorkbook.Unprotect Password:="yourpassword"
    DeleteSheetIfExists sheetName
    ThisWorkbook.Protect Password:="yourpassword", Structure:=True
End Sub
シートの保護は削除を妨げない

「シートの保護」(Worksheet.Protect)が有効でも、シート自体の削除はできます。削除できないときは、シートの保護ではなく「ブック構成の保護」を確認してください。

共有ブック(旧機能)の場合

従来の「ブックの共有」機能を使っている場合、シートの削除はできません。ExclusiveAccess で排他モードに切り替えてから削除します(ブックが保存済みである必要があり、他のユーザーは切断されます)。

Private Sub UnshareWorkbookAndDelete(ByVal sheetName As String)
    If ThisWorkbook.MultiUserEditing Then
        ThisWorkbook.ExclusiveAccess
    End If
    DeleteSheetIfExists sheetName
End Sub

なお、ブックの共有機能は現在では非推奨で、共同編集(OneDrive / SharePoint 上でのリアルタイム共同編集)への移行が推奨されています。

確認問題

確認問題
確認問題

まとめ

  • ワークシートの削除は Worksheets("シート名").Delete。対象ブックは ThisWorkbook などで明示する
  • 確認ダイアログは Application.DisplayAlerts = False で非表示にし、必ず True に戻す
  • 存在しないシートの削除はエラーになるため、存在確認をしてから削除する
  • 削除できない場合は、ブック構成の保護や共有ブックを疑う
#vba #Excelの操作 #worksheet #ワークシート