V4 V5

シート全体の状態は SheetProtectionws.Protection)が持ちます。保護は Excel と同じ 2 層です。セルは既定でロックされていて、そのロックは シートを保護してから効きます。つまり入力フォームを作る手順は、 「入力させたい範囲のロックを外す」→「シートを保護する」の順になります。

基本の流れ

using unvell.ReoGrid.Core;
using unvell.ReoGrid.Core.Protection;

// セルは既定でロック済み。まず入力させたい範囲を開ける
ws.SetRangeLock(RangePosition.Parse("B2:B100"), LockState.Unlocked);

// そのうえでシートを保護する。ここで初めてロックが効く
ws.Protect();

// パスワード付きで保護する(Unprotect を守るだけのもの。下記の注意を参照)
ws.Protect("hinagata");

ロック指定は範囲スコープの側テーブルProtectionTable)に入ります。列全体のロック解除でも エントリは 1 件で、セルには何も書きません。104 万行の列を開けてもコストは一定です。

判定は新しいエントリから順に矩形を差し引いて行うので、後から指定したものが勝ち、 セルを 1 つずつ調べることもありません。

許可する操作

// 保護中でも許可する操作を選ぶ(Excel の「シートの保護」ダイアログのチェック欄)
ws.Protection.AllowSort = true;
ws.Protection.AllowAutoFilter = true;
ws.Protection.AllowFormatCells = true;

// 選択そのものを禁じる(既定は両方 true = 選択できる)
ws.Protection.AllowSelectLockedCells = false;

ws.Protect();
プロパティ既定保護中に許可されるもの
AllowSelectLockedCellstrueロックされたセルの選択
AllowSelectUnlockedCellstrueロックされていないセルの選択
AllowFormatCellsfalseセルの書式変更
AllowFormatRows / AllowFormatColumnsfalse行高・列幅の変更
AllowInsertRows / AllowInsertColumnsfalse行・列の挿入
AllowDeleteRows / AllowDeleteColumnsfalse行・列の削除
AllowSortfalse並べ替え
AllowAutoFilterfalseオートフィルタの操作

選択系の 2 つだけ既定が逆である点に注意してください。OOXML はこれらのフラグを 「禁止」として持っており(insertRows="1" は「挿入を禁じる」の意味)、V5 は「許可」として持ちます。 選択の 2 つは元の既定が「禁じない」なので、反転すると true になります。 ここを取り違えると、誰もクリックできないシートが黙って出来上がります。

状態を調べる

bool on = ws.IsProtected;

// そのセルがロック指定かどうか(保護が off でも答えは返る)
bool locked = ws.IsCellLocked(1, 1);

// 実際にいま編集できるか = 保護が off、またはロックされていない
bool editable = ws.IsCellEditable(1, 1);

// 範囲まるごと。セル走査ではなく矩形の差し引きで答える
bool rangeOk = ws.IsRangeEditable(RangePosition.Parse("B2:B100"));

_ = (on, locked, editable, rangeOk);

IsCellLockedロック指定そのものを返し、保護が off でも答えます。 いま編集できるかを知りたいときは IsCellEditable を使ってください。

拒否を受け取る

ws.EditRefused += (_, e) =>
{
	// e.Reason は Cells / Axis / Structure
	// e.Message は Excel と同じ文面が入っている
	_ = $"{e.Reason}: {e.Message} ({e.Range?.ToAddress()})";

	// 自前で説明を出したなら Handled を立てる。コントロールの既定の警告が抑止される
	e.Handled = true;
};

ProtectionRefusedEventArgsReasonProtectionRefusal)は 3 種類です。

何が拒否されたか
Cells対象のセルがロックされている
Axis行・列の書式変更が許可されていない
Structure行・列の挿入・削除が許可されていない

Message には Excel と同じ文面が入っています。自前の案内を出したなら Handled を立ててください (コントロールの既定の警告が抑止されます)。どちらにせよ編集は拒否されます — ここから交渉はできません。 WinForms / WPF はメッセージボックス、Avalonia は標準のモーダルが無いためグリッド内の吹き出しで知らせます。

解除する

// パスワードが違えば false を返し、保護は解けない
bool ok = ws.Unprotect("hinagata");
_ = ok;

// ロック指定そのものを消す(保護とは独立)
ws.LockStates.Clear();

保護が効く範囲

効くのはユーザー操作だけです。 具体的には、編集の記録(recorder)を通る経路と 編集開始前の RequestEdit が関門になります。モデル API は開いたままなので、 ファイルローダーやホストアプリのコードは保護中のシートにも書けます。 Excel の UserInterfaceOnly と同じ線引きです。

パスワードについて

Protect(password) のパスワードは、Excel の16 ビットの検証値<sheetProtection password="…">) です。これは暗号ではありません — 総当たりどころか衝突が容易に作れる代物で、Excel 自身もそう扱っています。

V5 でも Unprotect を守る以上のことはしません。データを見せたくない用途には使わないでください。 ファイルを開ける人はセルの中身を読めます。保持しているのは、Excel で作ったブックが 作られたとおりに往復するためです。

Undo と I/O

  • ロック指定の変更はシートのスナップショットに載ります。
  • reogrid-json:シートの protection として保存されます。enabled と範囲の overrides は reogrid-web と同じ形で、passwordallow は V5 の拡張です。
  • XLSX<sheetProtection> として読み書きします。セル単位のロックは OOXML ではセル書式側 (<xf><protection locked="0"/>)にあるため、スタイルを通って往復し、読み込み時に範囲テーブルへ畳み直されます。

Studio で試す

Review ▸ Protect Sheet… / Unprotect Sheet…Review ▸ Lock Cells / Unlock Cells

次に読む

ページの内容は役に立ちましたか?