和風スパゲティのレシピ

日本語でコーディングするExcelVBA

シートを保護する - Worksheet.Protect

ワークシートの保護を設定/解除する方法を解説します。

シートを保護する

シートを保護するには、WorksheetオブジェクトのProtectメソッドを使用します。

Worksheets("○○").Protect

 
Protectメソッドは多数の引数を持ち、ほとんどの引数は

シートの保護ダイアログ

この「シートの保護」ダイアログと対応しています。

各設定と引数の対応は以下の通りです。

ダイアログの表示 引数名 規定値
パスワード Password
ロックされたセル範囲の選択 別プロパティ(後述)
ロックされていないセル範囲の選択 別プロパティ(後述)
セルの書式設定 AllowFormattingCells False
列の書式設定 AllowFormattingColumns False
行の書式設定 AllowFormattingRows False
列の挿入 AllowInsertingColumns False
行の挿入 AllowInsertingRows False
ハイパーリンクの挿入 AllowInsertingHyperlinks False
列の削除 AllowDeletingColumns False
行の削除 AllowDeletingRows False
並び替え AllowSorting False
オートフィルターの使用 AllowFiltering False
ピボットテーブル(グラフ)の使用 AllowUsingPivotTables False
オブジェクトの編集 DrawingObjects True
シナリオの編集 Scenarios True


例えば「ロックされたセルも書式設定はできるように」保護設定する場合は、

Worksheets("○○").Protect _
    AllowFormattingCells:=True , _
    AllowFormattingColumns:=True , _
    AllowFormattingRows:=True

このように記述します。


とりあえず「すべての設定を許可するコード」を置いておきますので、
禁止したい操作を消してご利用ください。

Worksheets("○○").Protect _
    Password:="xxx", _
    AllowFormattingCells:=True, _
    AllowFormattingColumns:=True, _
    AllowFormattingRows:=True, _
    AllowInsertingColumns:=True, _
    AllowInsertingRows:=True, _
    AllowInsertingHyperlinks:=True, _
    AllowDeletingColumns:=True, _
    AllowDeletingRows:=True, _
    AllowSorting:=True, _
    AllowFiltering:=True, _
    AllowUsingPivotTables:=True, _
    DrawingObjects:=False, _
    Scenarios:=False

細かい設定を行う場合はマクロ記録を利用するのもおすすめです。


なお、規定値がTRUEのものが2つありますが、
これは単にTrue/Falseの意味が他の引数と反対なだけです。

単純に「引数を省略したらすべて保護される」と覚えてください。


テキストボックスなどのオブジェクトを編集できるように保護するには、

DrawingObjects:= False

と、他引数とは違って「Falseにすると編集可能」になりますので、
この逆転にご注意ください。(なぜこんな仕様に・・・?)

条件設定は引き継げない点に注意

シートの保護ダイアログ

このダイアログをExcel上で操作するときは、前回の設定を記憶してくれます。


シートの保護を一旦解除して、また保護しようとしたとき、
前に付けたチェックはそのままにしてくれているのがわかります。


しかし、Protectメソッドはこの前回設定の記憶機能がありません。

手作業と同じイメージで、

ws.Unprotect

~保護を解除して編集し、終わったらまた保護~

.Protect

このようなコードを記述したくなりますが、

このコードは「マクロ実行前の保護」ではなく、
「すべてのチェックが外れた(すべて禁止している)保護」
を行ってしまっている点に注意してください。

同じ条件で保護しなおしたい場合は、Protectメソッドを実行するたびに、
しっかりとすべての引数を設定し直す必要があります。

セルの選択の制限

シートの保護ダイアログ

このダイアログの上2つは「セルの選択」に関するロックですが、
この2つはProtectメソッドではなく、
EnableSelectionプロパティで設定します。

' すべてのセル選択を禁止(チェックをどちらも外す)
Worksheets("○○").EnableSelection = xlNoselection

' ロックされたセルの選択を禁止(一番上だけチェックを外す)
Worksheets("○○").EnableSelection = xlUnlockedCells

' すべてのセル選択を許可
Worksheets("○○").EnableSelection = xlNoRestrictions

' いずれの設定もシートを保護しているときにのみ有効
Worksheets("○○").Protect

メソッドではなくプロパティですので、上記の通り代入によって状態を変更します。

ただし、これらはいずれも「保護したときに反映される」設定ですので、
最後にProtectメソッドを実行する必要があります。
(最初に実行し、保護した後で設定することもできます)


ちなみにチェックボックスが2つなのに設定値が3つしかないのは、
下だけチェックを外すことができないからです。

「ロックしたセルだけ選択可」という、不自然な設定にはできないということですね。

シートの追加/削除/名前変更の制限

勘違いしやすいポイントですが、
「シートの保護」で制限されるのはシートの中身(≒セル)の編集であり、
シート自体の追加や削除を制限する機能は「ブックの保護」です。

ブックの保護を行う場合は、
WorkbookオブジェクトのProtectメソッドを使います。


WorksheetオブジェクトのProtectメソッドと違い、
WorkbookオブジェクトのProtectメソッドは引数が(事実上)1つしかありません。

他の記事に誘導するほどでもないので、コードも置いておきます。
せっかくなので覚えてしまってください。

' ブックを保護
Workbooks("○○.xlsx").Protect

' ブックの保護を解除
Workbooks("○○.xlsx").Unprotect

' ブックを保護(パスワードあり)
Workbooks("○○.xlsx").Protect "1234"

' ブックの保護を解除(パスワードあり)
Workbooks("○○.xlsx").Unprotect "1234"

シートの保護を解除

シートの保護を解除する場合はUnprotectメソッドを使います。

Worksheets("○○").Unprotect

 
Unprotectメソッドの引数は「Password」のみです。
パスワード付の保護を解除する場合は、

Worksheets("○○").Unprotect "1234"

など、パスワードの文字列を引数に渡します。

シートが保護されているか調べる

シートが保護されているか調べるには、ProtectContentsプロパティを調べます。

ProtectContentsはそのシートが保護されていればTrue、
されていなければFalseを返します。

If Worksheets("○○").ProtectContents = True Then
    MsgBox "シートが保護されているため、処理を中断します。"
    Exit Sub
End If

 
一応留意点ですが、シートの保護を解除するUnprotectメソッドは、
保護されていないシートに実行してもエラーにはなりません。

つまり、「保護されていたら保護を解除する」処理を書きたいときは、

If Worksheets("○○").ProtectContents = True Then
    Worksheets("○○").Unprotect
End If

とわざわざ書く必要はありません。

Worksheets("○○").Unprotect

これだけで「保護されていたら保護を解除する」コードになっています。

保護シートへのProtect/非保護シートへのUnprotect実行

さきほど
「Unprotectメソッドは保護されていないシートに実行してもエラーにならない」
と説明しました通り、Unprotectメソッドは何時でも実行可能です。

そしてこれはProtectメソッドでも同様です。と、言いたいところなのですが・・・


Protectメソッドを保護シートへ実行する際は、
設定次第でなんとVBAのバグが発生します。


具体的には、引数DrawingObjectsまたはScenariosを指定したとき限定で、
なぜかシートの保護が外れてしまう
というバグが起きます。


とりあえず「Protectの前にUnpurotect」しておけば問題はありませんので、
シートの保護は保護を解除してから実行しましょう。

詳細はこちらの記事をどうぞ。
www.limecode.jp



以上でシートの保護に関する解説を終わります。


シートの保護/保護解除はコード自体は簡単なのですが、
Protectメソッドの引数が非常に多いため、
使うたびにいちいち引数名を調べる必要が出てしまうコードです。

全引数を指定したコードを再掲しておきますので、
シートの保護をよく行う方は、これを丸ごとどこかに保存しておきましょう。

Worksheets("○○").Protect _
    Password:="xxx", _
    AllowFormattingCells:=True, _
    AllowFormattingColumns:=True, _
    AllowFormattingRows:=True, _
    AllowInsertingColumns:=True, _
    AllowInsertingRows:=True, _
    AllowInsertingHyperlinks:=True, _
    AllowDeletingColumns:=True, _
    AllowDeletingRows:=True, _
    AllowSorting:=True, _
    AllowFiltering:=True, _
    AllowUsingPivotTables:=True, _
    DrawingObjects:=False, _
    Scenarios:=False