PC側の設定でExcelを読み取り専用で開くようにする

# 概要

Excelファイルをダブルクリックで開くときに「読み取り専用」で開くようにするスクリプトをまとめた話です。

# 背景

Excelファイルってあるじゃないですか。仕様書や設計書やTODO管理表にも使われる（使われてしまう）あいつです。

これらって多くの場合は「見たい」だけで変更はしたくない場合がほとんどだと思うんですよね。

でも、たとえば一時的に注目したいセルを黄色にしたいときってありますよね？自分はあります。でも更新タイムスタンプは変えたくない。

あとはカメラや内部参照のせいで開いただけで変更扱いになる罠Excelとかもありますよね。こういうのも更新はしたくない。

最後に閉じるときに保存しないを選べばいいだけではあるんですけど、誤って保存してしまうリスクを減らしておきたいですよね。

ということで、Excelを読み取り専用で開くように設定するスクリプトを作成しました。

ちなみに、今回のスクリプトはWindows専用なのでMacの方はごめんなさい🙇

# 読み取り専用とは？

* 開いたExcelファイルを上書き保存できなくなるモード

* タスクバー上に「読み取り専用」と表示されていれば読み取り専用モード

![読み取り専用の状態](https://www-tacos.github.io/qiita-images/20230817_excel_readonly/001.jpg)

* 保護モードと違って編集自体は可能で、別名を付ければ編集内容を保存することができる

  * 裏ワザっぽいが、元のファイル名を変えたうえで変更後の名前で保存すれば実質的に上書き保存ができる

* ファイル > 情報 > ブックの保護から「常に読み取り専用で開く」を設定した場合、ブックを開くと「読み取り専用で開きますか？」というダイアログが表示され、ここではいを選ぶと読み取り専用となる

  * いいえを選べば編集可能モードで開ける

![読み取り専用を設定する画面](https://www-tacos.github.io/qiita-images/20230817_excel_readonly/002.jpg)

# デフォルト動作を読み取り専用にするスクリプト

PowerShellで以下のスクリプトを順に実行すれば、Excelを開くときのデフォルトが読み取り専用になります。

ちなみにPowerShellといいつつ大半はコマンドプロンプトの呼び出しを使っています。残念ながら `assoc` と `ftype` がPowerShellから呼べないので。

## 1. 管理者権限でコンソールを開く

まず Windows PowerShell または Windows Terminal を管理者権限で開きます。以下のスクリプトを実行して True返ってくればOKです。

```powershell
# 管理者権限の有無の確認
[System.Security.Principal.WindowsPrincipal]::new(
  [System.Security.Principal.WindowsIdentity]::GetCurrent()
).IsInRole(
  [System.Security.Principal.WindowsBuiltInRole]::Administrator
)
```

## 2. Excelが紐づいている拡張子の確認

Excelアプリが紐づいている拡張子一覧が表示されるので、この中から読み取り専用で開くようにしたい拡張子を決めます。

```powershell
# Excelが紐づいている拡張子一覧の確認
cmd /c assoc | ? { $_ -like '*excel*' }
```

Excelのバージョンによって違いがあるかもしれませんが、おそらく以下のような結果が返ってくると思います。

```txt
.csv=Excel.CSV
.ods=Excel.OpenDocumentSpreadsheet.12
.slk=Excel.SLK
.xla=Excel.Addin
.xlam=Excel.AddInMacroEnabled
.xld=Excel.Dialog
.xlk=Excel.Backup
.xll=Excel.XLL
.xlm=Excel.Macrosheet
.xls=Excel.Sheet.8
.xlsb=Excel.SheetBinaryMacroEnabled.12
.xlshtml=Excelhtmlfile
.xlsm=Excel.SheetMacroEnabled.12
.xlsmhtml=excelmhtmlfile
.xlsx=Excel.Sheet.12
.xlt=Excel.Template.8
.xlthtml=Excelhtmltemplate
.xltm=Excel.TemplateMacroEnabled
.xltx=Excel.Template
.xlw=Excel.Workspace
.xlxml=Excelxmlss
```

ほとんどの場合は `.xls`, `.xlsx`, `.xlsm` の3つを変えるだけで十分だと思います。以降もいったんその体でスクリプトを書いています。

## 3. 実行コマンドへの読み取り専用オプションの付与

先ほど選んだ拡張子をEXCEL.EXEで開くときのコマンドに `/r` を追加して読み取り専用で開くようにします。

```powershell
# 読み取り専用オプションの付与
cmd /c assoc | ? {
  # 一部の拡張子についてのみ変更（必要に応じて適宜追加）
  $_ -match '^\.(xlsx|xlsm|xls)='
} | % {
  # ファイルタイプに関連づくコマンドを取得
  cmd /c ftype $($_.Split('=')[1]) 2>$null
} | % {
  # 実行ファイルに /r オプションを付与
  cmd /c "ftype $( $_ -replace '"(.*excel.exe)" "%1"$', '${1} /r "%1"' )"
}
```

正常に終了すれば以下のように変更後の設定値が表示されるかと思います。

```txt
Excel.Sheet.8=C:\Program Files\Microsoft Office\Root\Office16\EXCEL.EXE /r "%1"
Excel.SheetMacroEnabled.12=C:\Program Files\Microsoft Office\Root\Office16\EXCEL.EXE /r "%1"
Excel.Sheet.12=C:\Program Files\Microsoft Office\Root\Office16\EXCEL.EXE /r "%1"
```

# 編集モードで開くには？

上記の設定が通るとExcelファイルをダブルクリックで開くと読み取り専用で開かれます。

じゃあ編集したいときはどうするの？についてですが、対象のファイルを Shiftキー を押しながら右クリックすることでメニューの中に「編集(E)」が現れると思います。これを選べば編集可能なモードでファイルを開くことができます。

![編集で開く](https://www-tacos.github.io/qiita-images/20230817_excel_readonly/003.jpg)

# 変更を戻すには？

いちばん確実なのはクイック修復を行う方法で、これでExcelの起動設定を初期設定に戻すことができます。

> 参考: クイック修復の手順
> https://www.mediator.co.jp/support/archives/2988

ちなみに、同様の原理で、Excelを再インストールした時やアップデートしたときも設定が初期設定に戻ってしまいます。

<details>
<summary>※いちおう、スクリプトで戻す方法も書いておきます</summary>

```powershell
# 戻し
cmd /c assoc | ? {
  # 一部の拡張子についてのみ変更（必要に応じて適宜追加）
  $_ -match '^\.(xlsx|xlsm|xls)='
} | % {
  # ファイルタイプに関連づくコマンドを取得
  cmd /c ftype $($_.Split('=')[1]) 2>$null
} | % {
  # 設定
  cmd /c "ftype $( $_ -replace '=(.*excel.exe) /r "%1"$', '="${1}" "%1"' )"
}
```

</details>

# （補足）読み取り専用にする以外で上書きを回避する方法

今回は読み取り専用オプションを使って上書きを回避する方法を紹介しましたが、他にもいくつか方法があるので紹介しておきます。自分にあった方法を検討するのが一番ですからね。

## 方法A: ファイルのプロパティ上で読み取り専用にする

エクスプローラーでファイルを右クリックしたときにおそらく一番下に表示されている「プロパティ」を開いて、属性の「読み取り専用」にチェックを入れる方法です。

この方法を使うと、ブックは強制的に読み取り専用で開かれます。

また、前述の元ファイルをリネームして、その名前で上書きするという方法も使えないという特徴があります。（ファイル自体が読み取り専用になっているのでリネームしても上書きできない）

注意点として、ファイル共有サービス（DropboxとかOneDriveとか）で同期したときに属性がクリアされることがあるのは気を付けた方がいいかもしれません。

## 方法B: ブックの保護から常に読み取り専用で開くを設定する

これは先に述べたとおりですね。実態としては `/r` オプションをつけての読み取り専用とほぼ同じです。

ただし、ブックを開いたときに読み取り専用にするかしないかを選ぶ形なので、第三者に読み取り専用で開かせるにはちょうどいい方法だと思います。（とりあえずで編集可能で開く人もたまにいますが...）

## 方法C: 新規で開く

エクスプローラーでファイルを右クリックしたときに表示される「新規(N)」で開くと `{元のファイル名}{n}` という名前の新しいファイルで開くことができます。（nは1から始まる開いた順番）

あくまで新規ファイルなので Ctrl + S を押すと名前と保存場所を聞くダイアログが表示されます。

自分の周りだとこの方法を使ってる人が多かった印象です。特段、何か設定する必要もなく使える方法ですしね。

# さいごに

Excelを読み取り専用で開くようにするスクリプトと、ついでに上書きを回避する方法をいくつか紹介しました。

この記事でみなさんの不慮の上書きが少しでも減らせたら幸いです。

さいごまで読んでいただきありがとうございました。