この記事は、下記のような方におすすめです。
- Permissionエラーを出してしまうことが多い
- Permissionエラーを回避したい
- 対象のファイルを開いたまま、openpyxlで編集する方法を探している
この記事を読んでわかること。
- Permissionエラーの特徴がわかる
- Permissionエラーを回避する方法がわかる
- 対象のファイルを開いたままにしていても、そのファイルを編集する方法がわかる
ファイルを開いたままopenpyxlで編集する方法
結論からお伝えします。
「ファイルを開いたままopenpyxlで編集する方法」は、残念ながらありません。
openpyxlを使わない場合と同じなんです。
共有フォルダにあるエクセルファイルをAさんが開いていたら、
Bさんは編集して保存することができません(読み取り専用になる)
同じファイルを別々の人が違う内容で保存されてしまうのを防止するため、こういう仕様のようです。
あなたが開いているファイルをopenpyxlが編集して保存することができないのです。
じゃあダメなのか…と思うかもしれませんが、代替案はあります。
今回はその代替案を3つ紹介いたします。
代替案
今回紹介する代替案は下記の3つです。
- 別名保存する
- 別のフォルダに保存する
- 開いているファイルを自動で閉じる
すべて例外処理を利用します。
例外処理については下記記事をご参考ください。
併せて下記記事もお読みいただくと、理解しやすいかと思います。
別名保存する
まずは別名保存する代替案を紹介いたします。
「Permissionエラー」は、上書き保存をしようとした場合に発生するため、
別名保存をすることでエラーを回避できます。
import openpyxl
import datetime
date = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
try :
wb = openpyxl.load_workbook('C:/Utatane/input.xlsx')
ws = wb['Sheet1']
wb.save('C:/Utatane/input.xlsx')
except PermissionError :
wb = openpyxl.load_workbook('C:/Utatane/input.xlsx')
ws = wb['Sheet1']
ws['A1'] = 1
wb.save('C:/Utatane/input'+date+'.xlsx')
print('ファイルが開いたままでしたので、input'+date+'.xlsxという名前で保存しました。')
else :
wb = openpyxl.load_workbook('C:/Utatane/input.xlsx')
ws = wb['Sheet1']
ws['A1'] = 1
wb.save('C:/Utatane/input.xlsx')
「try:」でファイルを開いているかどうかを判定し、
ファイルを開いていれば「except PermissionError:」の処理を、
ファイルを開いていなければ「else:」の処理を行います。
実行結果:ファイルが開いたままでしたので、input20240516180558.xlsxという名前で保存しました。
フォルダ内を見ると、同じ名前のファイルがあり、キチンと編集されています。
▼input20240516180558.xlsx
※忘れないうちに、古い「input.xlsx」を削除し、このファイルの名前を「input.xlsx」に変更しておいてください。
解説:別名保存案
「except PermissionError :」の部分のみ解説いたします。
その他は「例外処理」や「開いているかどうか判定」の記事をご参考ください。
「except PermissionError :」の部分は、「Permissionエラー」が発生した際、
つまり「ファイルが開いたままの状態」の場合に行われる処理です。
except PermissionError :
wb = openpyxl.load_workbook('C:/Utatane/input.xlsx')
ws = wb['Sheet1']
ws['A1'] = 1
wb.save('C:/Utatane/input'+date+'.xlsx')
print('ファイルが開いたままでしたので、input'+date+'.xlsxという名前で保存しました。')
12~14行目で通常どおりファイルを開き、編集しています。
15行目が別名保存する記述です。
ファイル名に本日の日付+時間を付け足して、ファイル名が重複しないようにしています。
日付に関する操作は下記記事をご参考ください。
わかりやすいように、17行目でメッセージを表示しています。
「print」より「ダイアログ」でメッセージを表示させると、よりわかりやすいかと思います。
下記記事をご参考ください。
別のフォルダに保存する
次に別のフォルダに保存する代替案です。
同じファイル名の保存でも、別のフォルダに保存することで、「Permissionエラー」を回避できます。
import openpyxl
import os
import datetime
date = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
try :
wb = openpyxl.load_workbook('C:/Utatane/input.xlsx')
ws = wb['Sheet1']
wb.save('C:/Utatane/input.xlsx')
except PermissionError :
os.mkdir('C:/Utatane/'+date)
wb = openpyxl.load_workbook('C:/Utatane/input.xlsx')
ws = wb['Sheet1']
ws['A1'] = 1
wb.save('C:/Utatane/'+date+'/input.xlsx')
print('ファイルが開いたままでしたので、C:/Utatane/'+date+'に保存しました。')
else :
wb = openpyxl.load_workbook('C:/Utatane/input.xlsx')
ws = wb['Sheet1']
ws['A1'] = 1
wb.save('C:/Utatane/input.xlsx')
実行結果:ファイルが開いたままでしたので、C:/Utatane/20240516180522に保存しました。
フォルダ内を見ると、別のフォルダが作成されており、編集された「input.xlsx」が存在しています。
※忘れないうちに、このファイルを元フォルダに移動させておいてください。
解説:別フォルダ保存案
except PermissionError :
os.mkdir('C:/Utatane/'+date)
wb = openpyxl.load_workbook('C:/Utatane/input.xlsx')
ws = wb['Sheet1']
ws['A1'] = 1
wb.save('C:/Utatane/'+date+'/input.xlsx')
print('ファイルが開いたままでしたので、C:/Utatane/'+date+'に保存しました。')
13行目で保存するフォルダを作成しています。
前項のファイル名と同様に「date」を名前にすることで、重複しないようにしています。
フォルダ作成の方法は下記記事をご参考ください。
15~17行目でファイルを開いて編集し、
18行目で、ファルダ(13行目で作ったもの)に保存しています。
開いているファイルを自動で閉じる
最後に、開いているファイルを自動で閉じる代替案です。
この方法を利用すると、別のファイルやフォルダが作成されず、純粋に上書き保存ができます。
コードは少し長いですが、この方法が一番適切かと思います。あと少しですのでがんばりましょう。
import openpyxl
import xlwings
try :
wb = openpyxl.load_workbook('C:/Utatane/input.xlsx')
ws = wb['Sheet1']
wb.save('C:/Utatane/input.xlsx')
except PermissionError :
workbook = xlwings.books.active
workbook.save()
workbook.close()
wb = openpyxl.load_workbook('C:/Utatane/input.xlsx')
ws = wb['Sheet1']
ws['A1'] = 1
wb.save('C:/Utatane/input.xlsx')
print('ファイルが開いたままでしたので保存して閉じました。')
else :
wb = openpyxl.load_workbook('C:/Utatane/input.xlsx')
ws = wb['Sheet1']
ws['A1'] = 1
wb.save('C:/Utatane/input.xlsx')
実行結果:ファイルが開いたままでしたので保存して閉じました。
フォルダ内の「input.xlsx」を開くと、キチンと編集されていることがわかります。
開いている「input.xlsx」は閉じられてしまいますが、結果的に閉じるべきファイルですので、
一番効率的かと思います。
解説:ファイル閉じる案
except PermissionError :
workbook = xlwings.books.active
workbook.save()
workbook.close()
wb = openpyxl.load_workbook('C:/Utatane/input.xlsx')
ws = wb['Sheet1']
ws['A1'] = 1
wb.save('C:/Utatane/input.xlsx')
print('ファイルが開いたままでしたので保存して閉じました。')
「xlwings」を使用します。
これは手動と同じようにソフトを操作できるもので、実際にエクセルを開く・閉じるができるものと思ってください。
10~12行目で、現在開いているファイルを保存して閉じています。
あとは通常の処理と上書き保存で完了です。
保存させたくない場合は、11行目を削除してください。
xlwingsを初めて使う場合、インストールが必要となります。
まずは下記コードを実行して、インストールを完了させてください。
pip install xlwings
詳細は下記記事で解説しております。
最後に
ファイルを開いたままopenpyxlで編集できるのかを解説いたしました。
ファイルを開いたままopenpyxlで編集する方法は紹介できませんでしたが、
代替案で十分に満足できる結果になったのではないでしょうか。
当ブログでは、Pythonに関する情報を配信しております。
この記事がわかりやすいと感じた方は、他の記事も読んでいってください。
最後までお読みいただき、ありがとうございました。がんばってください!