面倒なExcel処理をPythonで自動化
1. まえがき
箇条書きで複数の条件が一つのセルに記入されているExcelファイルの各々の条件を、それぞれ別のセルに分割してほしいと依頼されました。
つまり下図のように別々のセルに分割したいようです。
これが項番500もあれば、残業も覚悟の作業になるわけですが、こういった面倒で手間な処理はPythonで処理して楽しましょうってお話です。
2. まずは元となるExcelの条件を整理
元ファイル名はcounter.xlsx
シートは1枚
確認項目に(1)・・・ (2)・・・と複数条件が記述されている場合、枝番をつけて分割する。
項番は500行、一つの項番に条件は最大で(20)まである。
3. PythonでExcelを利用するための環境構築
PythonでExcelを扱うため「openpyxl」を利用します。バージョンは執筆時点の最新にしました。簡単な処理なので、最新いれておけば大丈夫でしょう。(お気楽感をアピール!)
% pip install openpyxl
:
Successfully installed et-xmlfile-1.1.0 openpyxl-3.0.9
%
4.コーディング
あまり複雑に処理を書くのではなく、取り敢えず変更してCSVファイルにすれば、ExcelでCSVを開いてコピペできるようになるでしょう。これだけで、大分楽になるはずです。
CSVの出力も、あえてCSVファイルに書く処理は書かずに、標準出力に表示して、リダイレクトでファイルに出力すればこの部分のコーディングは不要ですよね!
今回は繰り返し使う処理ではなく、一時的な処理なんで、なるべく処理は簡単に!
てことでソースファイル名をconv.pyとして、コーディングを開始します。
まずはExcelファイルを開いて、シートを選択して、1行ずつ処理するところまで実装していきます。
import openpyxl
book = openpyxl.load_workbook('counter.xlsx')
sheet = book.active
for row in sheet.rows:
print(row)
続いて、B列の(=row[1])の分割を考えます。B列は(1)とか(2)といった括弧+数字で区切られているので、この条件で文字列を分割してみます。
括弧+数字は、正規表現で「\(\d+\)」と表現できるので、正規表現で分割可能な、re.splitを使えば分割できそうですね。
(分割前に、余分な改行が気になったので改行は一旦削除してます。)
import re
import openpyxl
book = openpyxl.load_workbook('counter.xlsx')
sheet = book.active
for row in sheet.rows:
col1 = row[1].value.replace('\n','')
col1s = re.split('\(\d+\)',col1)
col1s = re.split('\(\d+\)',col1)とすると、文字列が(n)で分割されリストになります。これをさらにfor文で回して、CSVっぽく表示します。
for文で回す際に、リストの何番目かを枝番にしたいので、enumerateを使ってリストの添字を返すようにしてます。
print文で「項番(A列),枝番,分割した条件」の順で表示してます。
for i, c1 in enumrate(col1s):
print('{},{},{}'.format(row[0].value, i, c1 )
さらにi=0は表示しないようにしたいので、下記の通り修正。
(三項演算子を使ってます。)
for i, c1 in enumrate(col1s):
print('{},{},{}'.format(row[0].value, i !=0 else '' , c1 )
といった感じで一通り処理はかけました。完成したソースがこちらです。
(ちょっとコメントつけて、見やすくしました。)
import re
import openpyxl
# Excelファイル[counter.xlsx]を開いて、アクティブなシートを選択する。
book = openpyxl.load_workbook('counter.xlsx')
sheet = book.active
# 選択したシート(sheet)を1行ずつ処理
for row in sheet.rows:
# A列:項番
col0 = row[0].value
# B列:確認項目の改行を削除
col1 = row[1].value.replace('\n','')
# B列:確認項目を(数字)単位で分割しcol1sにリスト形式で格納
col1s = re.split('\(\d+\)',col1)
# i = 添字 , c1 = 確認項目の条件
for i, c1 in enumrate(col1s):
# 項番,枝番,条件の順で表示 但し枝番0は''とし表示しない
print('{},{},{}'.format(col0, i !=0 else '' , c1 )
実行前に元のExcelの1行目のタイトル行の処理ができていませんが、プログラムを書くより、Excel開いて1行削除した方が早いので削除!
早速実行します。
% python conv.py
1,,サービス事業者は、○○を満たすことを、サービス利用者に説明する責任を果たすため、以下の責任を負うこと。
1,1,○○を文書化して提示すること。
1,2,○○に関する説明及び必要な情報提供を履行すること。
2,,サービスの利用者は、○○を履行すること。
:
%
良さそうなので、ファイルに出力
% python conv.py >counter.csv
あとは、Excelでcounter.csvを文字コードutf-8を指定して開いて、元のファイルにペタッとはれば依頼された作業は完了です。
5. あとがき
時間と精神がすり減りそうな繰り返し処理は、最近だとRPAを利用するっていうのを思いつく感じでしょうか。RPAはRPAで良い所もありますので、私はRPA否定派ではないですが、一からRPAを習得するなら、同じ手間でPython覚えるのも「有り?」って思っていただけたなら幸いです。
プログラミングを覚えれば、数時間の処理が数行程度のコーディングで完了し、10分足らずで終わらせることが出来るようになりますよ!
この記事が気に入ったらサポートをしてみませんか?