配布用のExcelシートで、「入力欄だけは編集できるようにしたいけれど、数式や見出しは誤って書き換えられたくない」というケースは多くあります。これを実現するのがRange.Lockedプロパティとシート保護の組み合わせです。
この記事では、セル単位でロック状態を制御し、特定のセルだけを編集可能にする方法をVBAコードとともに解説します。テンプレート配布や入力フォームの作成にそのまま使える内容です。
Range.Lockedプロパティの基本
Excelのすべてのセルには、既定でLocked = True(ロックされた状態)が設定されています。ただし、この設定はシート保護がかかっていない限り効果を発揮しません。つまり、シート保護をかけて初めてLockedの設定が意味を持つ、という仕組みです。
流れを整理すると以下のようになります。
- 編集させたいセル範囲だけ
Locked = Falseにする - それ以外のセルは
Locked = Trueのままにしておく(既定値なので何もしなくてOK) - シート全体に
Worksheet.Protectをかける
基本コード:入力欄だけ編集可能にする
以下は、B2:B10を入力欄として編集可能にし、それ以外は保護するコードです。
Sub SetupProtectedSheet()
Dim ws As Worksheet
Set ws = ActiveSheet
' 一旦シート保護を解除(既に保護されている場合のエラー防止)
ws.Unprotect
' 全セルをロック状態にする(既定値だが明示的に設定)
ws.Cells.Locked = True
' 入力欄だけロックを解除
ws.Range("B2:B10").Locked = False
' シート保護をかける
ws.Protect Password:="", DrawingObjects:=True, Contents:=True, Scenarios:=True
MsgBox "B2:B10のみ編集可能な状態で保護しました。"
End Sub
ws.Cells.Locked = Trueで全セルを一旦ロック状態に揃えてから、Range("B2:B10").Locked = Falseで入力欄だけ解除するのが基本パターンです。テンプレートを再利用するときに、以前設定したLockedの状態が残っていても、このコードなら毎回確実に同じ状態にリセットできます。
パスワード付きで保護する場合
ProtectメソッドのPassword引数にパスワードを指定すると、解除時にパスワードが要求されます。
Sub ProtectWithPassword()
Dim ws As Worksheet
Set ws = ActiveSheet
ws.Unprotect Password:="mypass123"
ws.Cells.Locked = True
ws.Range("B2:B10").Locked = False
ws.Protect Password:="mypass123"
End Sub
パスワードを設定した場合、Unprotectする際にも同じパスワードを渡す必要があります。パスワードをVBAコード内に直書きすると誰でも読めてしまうため、社外配布用のファイルでは注意が必要です。
保護を維持したままセルを更新するマクロ
保護されたシートに対して、マクロ側からは値を書き換えたいことがあります。そのたびにUnprotect→処理→Protectを繰り返すのは非効率なので、共通処理として関数化しておくと便利です。
Sub UpdateCellKeepingProtection(ws As Worksheet, targetCell As Range, newValue As Variant)
ws.Unprotect
targetCell.Value = newValue
ws.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
End Sub
Sub SampleUsage()
Call UpdateCellKeepingProtection(ActiveSheet, ActiveSheet.Range("D5"), "更新済み")
End Sub
UpdateCellKeepingProtectionプロシージャに保護解除・更新・再保護をまとめておくことで、呼び出し側のコードがシンプルになり、保護をかけ忘れる事故も防げます。
数式が入ったセルだけを保護する応用パターン
入力欄以外にも「数式が入っているセルだけ自動でロックする」という応用もよく使われます。SpecialCellsメソッドで数式セルを特定できます。
Sub LockFormulaCellsOnly()
Dim ws As Worksheet
Dim formulaCells As Range
Set ws = ActiveSheet
ws.Unprotect
' 一旦すべてロック解除
ws.Cells.Locked = False
On Error Resume Next
Set formulaCells = ws.Cells.SpecialCells(xlCellTypeFormulas)
On Error GoTo 0
If Not formulaCells Is Nothing Then
formulaCells.Locked = True
End If
ws.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
MsgBox "数式セルのみ保護しました。"
End Sub
SpecialCells(xlCellTypeFormulas)は対象セルが1つもない場合にエラーになるため、On Error Resume Nextで回避し、Nothing判定を挟んでいます。この応用パターンを使えば、シートの構成が変わっても「数式が入っているセル」を自動判定してロックできるため、メンテナンスの手間を減らせます。
まとめ
Range.Lockedプロパティは、シート保護(Worksheet.Protect)と組み合わせて初めて効果を発揮します。基本の流れは「全セルをロック→編集させたい範囲だけLocked=False→シート保護をかける」の3ステップです。
配布用テンプレートや入力フォームを作る際は、この仕組みを使うことで、見出しや数式を誤って書き換えられる事故を防ぎつつ、必要な入力欄だけを自由に編集できる状態にできます。


コメント