PythonでExcelを操り作業効率を上げよう
はじめに
かなりお久しぶりの投稿になってしまいました。。
最近はExcelを触ってごちゃごちゃすることが増えているこの頃です。
Excelであちこちに散らかっているブックのマッピングだったり、リストだったりが必要なケースはよくあります。
情報を整理したりマッピングしたりといった単純作業は正直時間を割きたくないですよね。(そんな時間あるならもっと価値あることをしたい…)
そこでPythonを使ってささっと作れないかを考えました。
自動化することのメリット
時間と精神が救われる
単純作業の場合、同じことを繰り返すのは時間的にも精神的にもきついヒューマンエラーを防げる
更新が必要になった場合、もう一度プログラムを実行するだけで再作成ができる
どんなことがPythonでできるの?
ほんの一部ですが、最近実施したことをいくつか紹介します。
Excelファイルをコピーする
リストから値を取得して、ファイル名を書き換える。
例)サンプルファイルをコピーして、「ID_成果物名.xlsx」というルールに基づいたファイルを大量に作成したい。
特定のidをキーにして、全角半角や大文字小文字の表記ゆれに対応しながらマッピングを作成する
例)2つのExcelファイルの差分や新旧対応表を知りたい。
フォーマットが決まっている全てのファイルに対して、特定のセルに値を書き込む。
例)表紙に自分の名前や日付をまとめて入れたい。
なぜVBAではなくPython
Excel操作としてはマクロ(VBA)が多いかと思いますが、以下の理由でPythonを使っています。
筆者がExcelに明るくない
VBAの記法を学習する時間がない
Pythonの方が使いやすいと思った
再帰的な処理がPythonの方が早い?
以前VBAでExcel操作を少しだけ行ったことがあるのですが、再帰処理に時間がすごくかかったイメージがありました
※ 書き方が悪かっただけかもしれません
環境
Pythonプログラムを実行できる環境が必要です。
Jupyterは実行を確認しながら作成できるのでオススメです。
インストール手順は割愛しますが、Jupyter Labを入れるのが一番初心者は簡単です。
使い方
よく使うPythonライブラリ
Openpyxlによるセルの読み書き
PythonでExcelを触るためのライブラリですshutilによるファイルのコピー
globによるフォルダ・ファイル一括取得 正規表現によるパターンマッチングができるので、特定のファイルに対して再帰的に処理をしたい場合に利用しました。
mojimojiによる半角全角置換 ファイルによって半角・全角が異なって困る!というケースがあり、統一するために利用しました。
xlwingによる図形操作 ほとんど利用していませんが、Excelマクロを直接動かして、図形を取得したりすることができるようです。今後利用するかもしれません。
シンプルなプログラム例
基本的にはすべて以下のような流れで作成しました。
※ 複数ファイルを読み込む場合はその数だけ★1,2を行います。
★1. 入力ファイルを読み込んで、対象範囲のブック・シート・セルを取得する
★2. セルをfor文でループさせて、値を行・列の2次元リストに格納する
★3. 最終的に出力したい行列のリストを作成する
★4. 出力ファイルにリストを出力する(参考)
import openpyxl
INPUT_PATH = 'C:\\input.xlsx'
OUTPUT_PATH = 'C:\\output.xlsx'
## ★1
# 入力ファイルを読み込んで、対象範囲のブック・シート・セルを取得する
#
wb = openpyxl.load_workbook(INPUT_PATH, data_only=True)
sheet = wb['Sheet']
rows = sheet['A4':'C9'] # セルの取得
## ★2
# セルをfor文でループさせて、値を行・列の2次元リストに格納する
# .valueでセルの値を取得可能
input_list = [[cell.value for cell in row] for row in rows]
## ★3
# ここはただのPythonのリスト操作
# 最終的に出力したい行列のリストを作る
## ★4
# 出力ファイルにリストを出力する
# ★3で作成したものはoutput_listというリストとする
wb = Workbook()
ws = wb.active
def write_list_2d(sheet, list_2d, start_row, start_col):
for y, row in enumerate(list_2d):
for x, cell in enumerate(row):
sheet.cell(row=start_row + y,
column=start_col + x,
value=list_2d[y][x])
write_list_2d(ws, output_list, 1, 1) # A1からoutput_listを出力
wb.save(OUTPUT_PATH)
wb.close()
Openpyxlの注意
公式ページに記載がありますが、Openpyxlの操作によって画像や図形が消えてしまうことがあります。
実際に図形が消えてしまって少し焦りました。(笑)
図形があるファイルをいじる場合は、後から張りなおせるようにしておくか、xlwingsやVBAと組み合わせて利用することが必要みたいです。
おわりに
先日Pythonでマッピングしたもので、参照元のファイルに大幅更新が入りました。
これまた更新するってなかなか手間ですよね、、、?と聞かれましたが、
いや?もう一度走らせるだけなので!とドヤれました(笑)
なんでもなるべく自動化できないかを考えることは大事ですね。