【ExcelVBA・マクロ】Range.Lockedとシート保護の使い方|特定セルだけ編集可能にする方法【コピペOK】

ExcelVBA

配布用のExcelシートで、「入力欄だけは編集できるようにしたいけれど、数式や見出しは誤って書き換えられたくない」というケースは多くあります。これを実現するのがRange.Lockedプロパティとシート保護の組み合わせです。

この記事では、セル単位でロック状態を制御し、特定のセルだけを編集可能にする方法をVBAコードとともに解説します。テンプレート配布や入力フォームの作成にそのまま使える内容です。

スポンサーリンク
スポンサーリンク

Range.Lockedプロパティの基本

Excelのすべてのセルには、既定でLocked = True(ロックされた状態)が設定されています。ただし、この設定はシート保護がかかっていない限り効果を発揮しません。つまり、シート保護をかけて初めてLockedの設定が意味を持つ、という仕組みです。

流れを整理すると以下のようになります。

  1. 編集させたいセル範囲だけLocked = Falseにする
  2. それ以外のセルはLocked = Trueのままにしておく(既定値なので何もしなくてOK)
  3. シート全体に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ステップです。

配布用テンプレートや入力フォームを作る際は、この仕組みを使うことで、見出しや数式を誤って書き換えられる事故を防ぎつつ、必要な入力欄だけを自由に編集できる状態にできます。

スポンサーリンク
スポンサーリンク
ExcelVBA
シェアする
いがぴをフォローする

コメント

タイトルとURLをコピーしました