PythonのopenpyxlライブラリでExcelファイルを作成・編集できるのは非常に便利ですが、作成したファイルを他人に共有する際には、「数式を壊されたくない」「入力してほしいセル以外は触らせたくない」といった悩みが出てきます。
この記事では、そんな悩みを解決するopenpyxlのシート保護機能、SheetProtectionオブジェクトの使い方を徹底的に解説します。
この記事を読めば、Pythonでパスワード付きの保護されたExcelシートを作成し、特定の操作のみを許可する、といった高度な制御ができるようになります。
はじめに:なぜシートの保護が必要か?
まず、Excelにおけるシート保護の目的と、openpyxlでの役割を確認しましょう。
意図しない変更の防止
シートを保護する最大の目的は、エンドユーザーによる意図しない変更や誤操作を防ぐことです。特に、複雑な数式が入力されたセルや、マスターデータとして利用するシートを誤って編集されてしまうと、ファイル全体が機能しなくなる可能性があります。シート保護は、そうしたリスクを低減させるための重要な機能です。
SheetProtectionオブジェクトの役割
openpyxlでは、このシート保護に関するすべての設定をWorksheetオブジェクトが持つprotection属性(SheetProtectionオブジェクト)を通じて行います。このオブジェクトのプロパティを操作することで、パスワードの設定や、許可する操作のカスタマイズが可能です。
もっとも簡単なシート保護:パスワード付きで全体をロックする
まずは基本として、シート全体を編集不可にし、解除用のパスワードを設定する方法を見ていきましょう。
SheetProtectionオブジェクトを取得する
シート保護の設定は、ワークシートオブジェクトのprotection属性にアクセスすることから始まります。
from openpyxl import Workbook
# 新しいワークブックとワークシートを作成
wb = Workbook()
ws = wb.active
ws.title = "保護されたシート"
# A1セルにデータを入力
ws['A1'] = "このセルは編集できません"
# シートのprotection属性を取得
sheet_protection = ws.protectionパスワードを設定し、保護を有効にする
SheetProtectionオブジェクトには、保護を有効にするためのsheetプロパティと、パスワードを設定するpasswordプロパティがあります。
sheet_protection.sheet = True: これでシートの保護が有効になります。sheet_protection.password = 'あなたのパスワード': 保護を解除するためのパスワードを設定します。
サンプルコード:シート全体を保護する
これらを組み合わせると、以下のようなコードになります。
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws.title = "保護されたシート"
ws['A1'] = "このセルは編集できません"
ws['B1'] = 12345
# シート保護を有効にする
ws.protection.sheet = True
# パスワードを設定する
# パスワードはExcelの仕様上、比較的簡易なハッシュ化しかされない点に注意してください。
ws.protection.password = 'himitsu'
# ファイルを保存
wb.save("protected_sheet.xlsx")このコードで生成されたprotected_sheet.xlsxを開くと、シートが保護されており、セルを編集しようとすると警告が表示されます。「シート保護の解除」からパスワードhimitsuを入力すれば、再び編集できるようになります。
保護しつつ特定の操作を許可するカスタマイズ
シート全体をガチガチに固めるだけでなく、「並べ替えだけは許可したい」「セルの色付け(書式設定)はOKにしたい」という場合もあります。SheetProtectionオブジェクトの各種プロパティをTrueに設定することで、特定の操作を許可できます。
SheetProtectionの便利な属性(プロパティ)
以下によく使われるプロパティをまとめます。デフォルトではすべてFalse(不許可)です。
| プロパティ名 | 許可する操作 |
allowFormatCells | セルの書式設定 |
allowFormatRows | 行の書式設定 |
allowFormatColumns | 列の書式設定 |
allowInsertRows | 行の挿入 |
allowInsertColumns | 列の挿入 |
allowDeleteRows | 行の削除 |
allowDeleteColumns | 列の削除 |
allowSort | 並べ替え |
allowAutoFilter | オートフィルター |
allowPivotTables | ピボットテーブルの操作 |
コード例:セルの書式設定と並べ替えを許可する
例えば、セルの編集は防ぎたいけれど、見た目の変更(色付けなど)とデータの並べ替えはユーザーに許可したい場合は、以下のように設定します。
# ... wsの準備までは省略 ...
# 並べ替えとセルの書式設定を許可
ws.protection.allowSort = True
ws.protection.allowFormatCells = True
# シート保護を有効化 & パスワード設定
ws.protection.sheet = True
ws.protection.password = 'himitsu'
wb.save("partially_allowed.xlsx")【最重要】特定のセルだけ編集を許可する方法
実務で最も多いのが、「特定の入力欄だけ編集を許可し、数式や見出しは保護したい」というケースです。これを実現するには、Excelの「セルのロック」の概念を理解する必要があります。
Excelの「セルのロック」と「シート保護」の関係
Excelの保護は2段階の仕組みになっています。
- セルのロック設定: すべてのセルには、デフォルトで「ロック」属性がオンになっています。
- シート保護: シート保護を有効にすると、この「ロック」属性がオンのセルの編集が禁止されます。
つまり、**特定のセルだけ編集を許可するには、「①対象セルのロックを外し」てから、「②シート保護を有効にする」**という手順を踏む必要があります。
openpyxlでセルのロックを解除する
セルのロック属性は、セルオブジェクトのprotection属性にあるlockedプロパティで制御します。デフォルトはTrue(ロック)なので、これをFalse(ロック解除)に変更します。
実践コード:数式以外(A1セル)の入力だけを許可する
以下の例では、B1セルに数式を入れ、ユーザーにはA1セルだけ入力させたい、というシナリオを実装します。
from openpyxl import Workbook
from openpyxl.styles import Protection
wb = Workbook()
ws = wb.active
ws.title = "入力フォーム"
# 見出しと数式の設定
ws['A1'] = "ここに数値を入力"
ws['B1'] = "=A1*1.1" # A1の値に10%加算する数式
ws['A2'] = "(B1セルは数式なので編集不可)"
# A1セルのみ編集を許可するためにロックを解除する
# セルオブジェクトのprotection属性のlockedをFalseにする
cell_a1 = ws['A1']
cell_a1.protection = Protection(locked=False)
# シート保護を有効にする
ws.protection.sheet = True
ws.protection.password = 'pass123'
# ファイルを保存
wb.save("input_form.xlsx")このExcelファイルを開くと、A1セルには自由に入力できますが、数式が入っているB1セルを編集しようとするとエラーになります。これにより、安全な入力フォームをPythonで作成できました。
まとめ:SheetProtectionで安全なExcelファイルを作ろう
今回はopenpyxlのシート保護機能SheetProtectionについて詳しく解説しました。最後に重要なポイントをまとめます。
- 基本保護:
ws.protection.sheet = Trueで有効化し、ws.protection.password = '...'でパスワードを設定する。 - 操作の許可:
allowSortやallowFormatCellsなどのプロパティをTrueにすると、保護下でもその操作を許可できる。 - 特定セルの編集許可: 最も重要なテクニック。対象セルの
protection.lockedをFalseに設定してから、シート全体を保護する。
これらの機能を使いこなすことで、単にデータを書き出すだけでなく、より安全で実用的なExcelファイルをPythonから直接生成できます。ぜひ、業務の自動化などにご活用ください。


コメント