Excel VBAで処理を自動化していると、「保護されたシートに値を入力できない」「マクロ実行時にエラーになる」「処理後に保護を戻し忘れる」といった問題が発生することがあります。
特に実務では、入力ミスを防ぐためにシート保護を設定しているファイルも多く、VBAで一時的に保護を解除して処理し、最後に再度保護する設計がよく使われます。
ただし、Unprotect と Protect は便利な反面、パスワードの扱いやエラー発生時の復旧を考えずに使うと、意図せずシートが編集可能な状態のまま残ってしまうことがあります。
この記事では、VBAでシート保護を解除・再設定する基本構文から、パスワード付き保護、実務で安全に使うための設計ポイントまで解説します。
✅ VBAでシート保護と解除を行う基本
VBAで保護シートを操作する場合、まず理解しておきたいのが「処理前に解除し、処理後に再保護する」という基本の流れです。
この流れを押さえずに保護されたシートへ値を書き込もうとすると、実行時エラーが発生することがあります。
特に、手動では編集できないセルに対してVBAで入力・削除・貼り付けを行う場合は注意が必要です。
また、保護解除だけを行って再保護を忘れると、ユーザーが誤って数式や固定セルを変更できる状態になってしまいます。
そのため、シート保護のVBA処理では「解除」と「再保護」をセットで考えることが重要です。
・シート保護を解除する基本構文
Sub UnprotectSheetBasic()
Worksheets("入力シート").Unprotect
End Sub
このコードは、「入力シート」という名前のシート保護を解除します。
パスワードなしで保護されている場合は、このように Unprotect だけで解除できます。
・シートを保護する基本構文
Sub ProtectSheetBasic()
Worksheets("入力シート").Protect
End Sub
このコードは、指定したシートを保護します。
ただし、実務ではパスワード付きで保護するケースが多いため、次のように書くことが一般的です。
Sub ProtectSheetWithPassword()
Worksheets("入力シート").Protect Password:="sample123"
End Sub
パスワードを指定することで、簡単に保護を解除されにくくできます。
✅ VBAでパスワード付きシート保護を解除する方法
パスワード付きで保護されたシートをVBAから解除する場合は、Unprotect に Password を指定します。
ここでパスワードが間違っているとエラーになるため、実務ではパスワード文字列の管理にも注意が必要です。
また、コード内にパスワードを直接書くと、VBEを開ける人には見えてしまう点も理解しておく必要があります。
シート保護は「誤操作防止」のための機能であり、強固なセキュリティ対策として過信しないことが大切です。
とはいえ、日常業務で数式セルやレイアウトを守る目的では非常に有効です。
・Passwordを指定して保護解除するコード
Sub UnprotectSheetWithPassword()
Worksheets("入力シート").Unprotect Password:="sample123"
End Sub
このコードでは、パスワード sample123 を使ってシート保護を解除しています。
パスワードが一致しない場合、保護は解除されません。
・Passwordを指定して再保護するコード
Sub ProtectSheetWithPasswordAgain()
Worksheets("入力シート").Protect Password:="sample123"
End Sub
解除時と同じパスワードで再保護しておくことで、処理後もユーザーの誤操作を防げます。
シート保護は「完全に編集禁止にする」だけでなく、“必要なセルだけ編集可能にする”運用も実務では非常によく使われます。
特に入力フォームや申請書では、数式セルや固定項目を守りながら、入力欄だけ編集できるように設計するケースが多くあります。
▶ 「【Excel】シート保護 一部|特定セルだけ編集可能にする方法を丁寧に解説」では、実務で使いやすい部分保護の設定方法や、安全な入力シート設計の考え方を詳しく解説しています。
✅ VBA処理中だけ保護を解除して最後に戻す実務コード
実務では、単に保護を解除するだけでなく、「必要な処理を行った後に必ず保護を戻す」ことが重要です。
例えば、入力シートに計算結果を転記したり、不要な行を削除したりする場合、保護されたままでは処理できないことがあります。
しかし、解除したまま処理を終了すると、あとで別のユーザーが数式や見出しを変更してしまうリスクがあります。
そのため、VBAでは処理の前後を明確に分け、保護状態を管理する設計が安全です。
ここでは、実務で使いやすい基本パターンを紹介します。
・保護解除から再保護までをまとめたコード
Sub UpdateProtectedSheet()
Dim targetSheet As Worksheet
Dim sheetPassword As String
Set targetSheet = Worksheets("入力シート")
sheetPassword = "sample123"
' 処理前にシート保護を解除する
targetSheet.Unprotect Password:=sheetPassword
' 保護解除中に必要な処理を行う
targetSheet.Range("B2").Value = Date
targetSheet.Range("C2").Value = "更新済み"
' 処理後に再度シートを保護する
targetSheet.Protect Password:=sheetPassword
End Sub
このコードでは、処理対象のシートとパスワードを変数で管理しています。
・この書き方が実務で使いやすい理由
このコードでは、シート名やパスワードを直接何度も書かず、変数にまとめています。
そのため、後からシート名やパスワードを変更する場合でも、修正箇所が分かりやすくなります。
また、targetSheet という変数名にすることで、「どのシートを操作しているのか」がコード上で読み取りやすくなります。
単に短く書くだけなら、次のようにも書けます。
Worksheets("入力シート").Unprotect Password:="sample123"
Worksheets("入力シート").Range("B2").Value = Date
Worksheets("入力シート").Protect Password:="sample123"
ただし、この書き方は処理が増えたときに読みづらくなり、同じシート名やパスワードを何度も書くため、修正漏れが起きやすくなります。
実務で長く使うマクロでは、少し丁寧に変数化しておく方が安全です。
✅ エラーが起きてもシート保護を戻す設計
シート保護を扱うVBAで特に注意したいのが、処理途中でエラーが発生した場合です。
保護を解除したあとにエラーでマクロが止まると、シートが解除されたまま残ってしまう可能性があります。
これは実務ではかなり危険で、入力禁止にしていたセルや数式セルが編集可能な状態になることがあります。
そのため、保護解除を伴う処理では、エラー発生時にも再保護する仕組みを入れておくことが大切です。
「正常に動く場合」だけでなく、「失敗した場合にどう戻すか」まで考えることで、実務向けの安全なコードになります。
・エラー時も保護を戻すコード
Sub UpdateProtectedSheetWithErrorHandling()
Dim targetSheet As Worksheet
Dim sheetPassword As String
On Error GoTo ErrorHandler
Set targetSheet = Worksheets("入力シート")
sheetPassword = "sample123"
' 処理前に保護を解除する
targetSheet.Unprotect Password:=sheetPassword
' 保護解除中に行う処理
targetSheet.Range("B2").Value = Date
targetSheet.Range("C2").Value = "更新済み"
' 正常終了時も必ず保護を戻す
targetSheet.Protect Password:=sheetPassword
MsgBox "処理が完了しました。", vbInformation
Exit Sub
ErrorHandler:
' エラー発生時もシートを保護状態に戻す
If Not targetSheet Is Nothing Then
targetSheet.Protect Password:=sheetPassword
End If
MsgBox "処理中にエラーが発生しました。シート保護は再設定しました。", vbExclamation
End Sub
・安全に終了できる流れを作ることが重要
このコードでは、処理中にエラーが発生した場合でも ErrorHandler に移動し、シートを再保護するようにしています。
単に On Error Resume Next でエラーを無視する方法もありますが、それでは「どこで失敗したのか」が分かりにくくなります。
特に保護解除を伴う処理では、エラーを無視するよりも、安全に終了するための出口を用意する方が実務向きです。
エラー処理では、「とりあえず止まらないようにする」だけでは不十分です。
特に On Error Resume Next を安易に使うと、本来気付くべきエラーを見逃し、シート保護解除漏れやデータ不整合につながるケースもあります。
▶ 「【VBA】On Error Resume Nextでエラーを無視してエラーの制御|危険な理由」では、エラーを無視する書き方のリスクや、実務で安全にエラー制御するための考え方を詳しく解説しています。
✅ Protectメソッドで設定できる主なオプション
Protect メソッドでは、単にシートを保護するだけでなく、操作の許可範囲を細かく設定できます。
たとえば、保護中でもフィルター操作を許可したり、並べ替えを許可したりすることが可能です。
実務では、「すべて禁止」ではなく、「入力してほしくない場所だけ守る」という設計が使いやすい場合もあります。
特に管理表や一覧表では、保護中でもフィルターや並べ替えを使いたい場面が多くあります。
そのため、Protectのオプションを理解しておくと、使いやすさと安全性を両立しやすくなります。
・フィルター操作を許可して保護するコード
Sub ProtectSheetAllowFilter()
Dim targetSheet As Worksheet
Dim sheetPassword As String
Set targetSheet = Worksheets("入力シート")
sheetPassword = "sample123"
targetSheet.Protect _
Password:=sheetPassword, _
AllowFiltering:=True
End Sub
このコードでは、シート保護を行いながら、フィルター操作を許可しています。
・並べ替えも許可するコード
Sub ProtectSheetAllowSortAndFilter()
Dim targetSheet As Worksheet
Dim sheetPassword As String
Set targetSheet = Worksheets("入力シート")
sheetPassword = "sample123"
targetSheet.Protect _
Password:=sheetPassword, _
AllowSorting:=True, _
AllowFiltering:=True
End Sub
保護中でも並べ替えやフィルターを使いたい場合は、このようにオプションを指定します。
ただし、並べ替えを許可する場合は、対象範囲のセルが適切にロック解除されている必要があります。
シート保護を設定する際は、「どの操作を禁止し、どの操作を許可するか」を業務内容に合わせて設計することが重要です。
特に一覧表では、保護中でもフィルター操作を使いたいケースが多く、AllowFiltering の設定が実務でよく利用されます。
▶ 「【VBA】フィルター機能【複数条件・複数列フィルター】の操作設定|AutoFilterを実務で」では、AutoFilterを安全かつ実践的に扱うためのVBA設定方法を詳しく解説しています。
✅ UserInterfaceOnlyでマクロだけ編集可能にする方法
実務では、「ユーザーには編集させたくないが、VBAでは編集したい」という場面があります。
その場合に便利なのが、UserInterfaceOnly:=True の指定です。
これを使うと、画面上ではシートが保護されたままでも、VBAからはセルの変更ができるようになります。
ただし、この設定はブックを閉じると保持されないため、開くたびに再設定する必要があります。
この点を知らずに使うと、「昨日は動いたのに今日はエラーになる」という原因になるため注意が必要です。
・VBAからの編集だけ許可するコード
Sub ProtectSheetForMacroOnly()
Dim targetSheet As Worksheet
Dim sheetPassword As String
Set targetSheet = Worksheets("入力シート")
sheetPassword = "sample123"
targetSheet.Protect _
Password:=sheetPassword, _
UserInterfaceOnly:=True
End Sub
このコードでは、ユーザー操作では保護されたままですが、VBA処理ではセルを書き換えられるようになります。
・実務で使うときの注意点
UserInterfaceOnly:=True は便利ですが、設定が保存されない点に注意が必要です。
そのため、実務では Workbook_Open イベントで、ブックを開いたときに再設定する方法がよく使われます。
Private Sub Workbook_Open()
Dim targetSheet As Worksheet
Dim sheetPassword As String
Set targetSheet = ThisWorkbook.Worksheets("入力シート")
sheetPassword = "sample123"
targetSheet.Protect _
Password:=sheetPassword, _
UserInterfaceOnly:=True
End Sub
このコードは、ThisWorkbook モジュールに記述します。
✅ 複数シートをまとめて保護・解除する方法
実務ファイルでは、1枚だけでなく複数のシートをまとめて保護・解除したいことがあります。
たとえば、月次集計ブックや部署別シートでは、同じ保護設定を複数シートに適用するケースがよくあります。
このとき、同じコードをシート数分だけ書くと、後から修正が大変になります。
そのため、複数シートをループで処理する構成にしておくと、保守性が高くなります。
シート追加や名前変更にも対応しやすくなるため、実務では非常に使いやすい考え方です。
・すべてのシートをまとめて保護するコード
Sub ProtectAllSheets()
Dim targetWorkbook As Workbook
Dim targetSheet As Worksheet
Dim sheetPassword As String
Set targetWorkbook = ThisWorkbook
sheetPassword = "sample123"
For Each targetSheet In targetWorkbook.Worksheets
targetSheet.Protect Password:=sheetPassword
Next targetSheet
End Sub
・すべてのシートをまとめて解除するコード
Sub UnprotectAllSheets()
Dim targetWorkbook As Workbook
Dim targetSheet As Worksheet
Dim sheetPassword As String
Set targetWorkbook = ThisWorkbook
sheetPassword = "sample123"
For Each targetSheet In targetWorkbook.Worksheets
targetSheet.Unprotect Password:=sheetPassword
Next targetSheet
End Sub
・ループ処理にするメリット
この書き方にしておくと、シートが増えてもコードを増やす必要がありません。
また、保護対象を一括管理できるため、保護漏れや解除漏れを防ぎやすくなります。
ただし、すべてのシートを対象にすると、保護したくない作業用シートまで保護される可能性があります。
その場合は、シート名で除外条件を入れると安全です。
Sub ProtectSheetsExceptWorkSheet()
Dim targetWorkbook As Workbook
Dim targetSheet As Worksheet
Dim sheetPassword As String
Set targetWorkbook = ThisWorkbook
sheetPassword = "sample123"
For Each targetSheet In targetWorkbook.Worksheets
' 作業用シートは保護対象から除外する
If targetSheet.Name <> "作業用" Then
targetSheet.Protect Password:=sheetPassword
End If
Next targetSheet
End Sub
✅ シート保護の状態を確認してから処理する方法
VBAで保護解除や再保護を行う場合、現在の保護状態を確認してから処理すると安全です。
すでに保護されていないシートに対して解除処理を行っても大きな問題にならないことはありますが、実務では状態を明確にしておく方が保守しやすくなります。
また、処理後に「もともと保護されていた場合だけ再保護する」という設計にしたいこともあります。
このような場合は、ProtectContents プロパティを使って保護状態を確認できます。
状態を見て処理を分岐させることで、より実務に強いマクロになります。
・ProtectContentsで保護状態を確認するコード
Sub CheckSheetProtectionStatus()
Dim targetSheet As Worksheet
Set targetSheet = Worksheets("入力シート")
If targetSheet.ProtectContents Then
MsgBox "このシートは保護されています。", vbInformation
Else
MsgBox "このシートは保護されていません。", vbInformation
End If
End Sub
・もともと保護されていた場合だけ再保護するコード
Sub UpdateSheetKeepOriginalProtection()
Dim targetSheet As Worksheet
Dim sheetPassword As String
Dim wasProtected As Boolean
Set targetSheet = Worksheets("入力シート")
sheetPassword = "sample123"
' 処理前の保護状態を記録する
wasProtected = targetSheet.ProtectContents
If wasProtected Then
targetSheet.Unprotect Password:=sheetPassword
End If
' 必要な処理を行う
targetSheet.Range("B2").Value = Date
If wasProtected Then
targetSheet.Protect Password:=sheetPassword
End If
End Sub
このコードでは、処理前の保護状態を記録しておき、もともと保護されていた場合だけ再保護しています。
共有ファイルや既存帳票を扱う場合に便利な考え方です。
✅ VBAでシート保護を扱うときの注意点
シート保護は便利ですが、実務で扱う場合はいくつか注意点があります。
特に、パスワードをコード内に直接書く場合や、処理途中でエラーが起きる場合は慎重に設計する必要があります。
また、シート保護はあくまで誤操作防止の仕組みであり、重要情報を完全に守るための強力なセキュリティ機能として過信しない方が安全です。
一方で、入力範囲を限定したり、数式セルを守ったりする目的では非常に有効です。
ここでは、実務で使う前に押さえておきたい注意点を整理します。
・パスワードの直書きには注意する
sheetPassword = "sample123"
このようにコード内にパスワードを書くと、VBEを開ける人には見えてしまいます。
そのため、重要なパスワードをそのまま書くのは避けた方が安全です。
実務では、あくまで誤操作防止用と割り切ることが大切です。
・保護解除後の再保護漏れに注意する
シート保護処理で最も避けたいのは、解除したまま処理が終わることです。
特にエラー時や途中終了時は再保護漏れが起きやすいため、エラー処理を入れておくと安全です。
・保護中に許可する操作を決めておく
すべての操作を禁止すると、ユーザーが使いづらいファイルになることがあります。
実務では、
- 入力セルだけ編集可能にする
- フィルターは使えるようにする
- 並べ替えは必要に応じて許可する
など、業務に合わせた設計が大切です。
✅ まとめ:VBAのシート保護と解除は安全に戻す設計が重要
VBAでシート保護と解除を扱う場合は、単に Unprotect と Protect の構文を覚えるだけでは不十分です。
実務では、処理の前後で保護状態を正しく管理し、エラーが発生しても安全に戻せる設計が重要になります。
- シート保護の解除には
Unprotectを使う - シート保護の設定には
Protectを使う - パスワード付きの場合は
Passwordを指定する - 処理前に解除し、処理後に再保護する
- エラー時にも保護を戻す設計にする
- 必要に応じて
AllowFilteringやAllowSortingを使う UserInterfaceOnlyを使うと、ユーザー操作は制限しつつVBA処理は可能にできる- 複数シートはループでまとめて管理すると保守しやすい
ProtectContentsで保護状態を確認できる
シート保護は、Excelファイルを安全に運用するための重要な仕組みです。
VBAと組み合わせることで、ユーザーの誤操作を防ぎながら、必要な処理だけを自動化できます。
「解除して処理する」だけで終わらせず、「最後に確実に保護へ戻す」ことまで含めて設計すると、実務でも安心して使えるマクロになります。