このページで解説している内容は、以下の YouTube 動画の解説で見ることができます。
【Python入門】Excelの作業を自動化する

Excelの作業を自動化する
Excelでの繰り返し作業や集計処理をプログラムに任せれば、大量のデータを扱う場合でも一瞬で結果を出せる上、人的ミスの防止にもつながります。openpyxlを使ったExcelの自動化は、毎回手動で行っていたファイル操作をまとめて処理し、業務効率化を実現する強力な手段となります。ここでは、その一例として商品の合計金額を計算してセルに書き込む簡単なプログラムを紹介します。

プログラムのダウンロード
「ダウンロード」から、JupyterLab で実行できるサンプルプログラムがダウンロードできます。ファイルは、ESET Endpoint Securityでウイルスチェックをしておりますが、ダウンロードとプログラムの実行は自己責任でお願いいたします。
1.Excelの作業を自動化するメリット
- 大量データの一括処理:膨大なファイルや行数があっても、プログラムなら素早く処理できます。
- 入力ミスの減少:人手で行う複雑なコピペや転記作業が不要になるため、ヒューマンエラーを大幅に削減します。
- 再利用性の高さ:一度作ったスクリプトは、ファイル名やシート名を変えるだけで再利用できます。
- 定型業務の軽減:毎日や毎週のように同じ作業を行う場合でも、一度プログラムを組めば繰り返し実行するだけで済みます。
2.合計を自動計算して書き込む例
ここでは、下表のようなExcelファイル「inventory.xlsx」を想定します。列Aに商品名、列Bに価格を入力しており、最終的に列Aに「Sum」というラベル、列Bに合計額を書き込みたいとします。すでに「Sum」が存在する場合は、追記処理を上書き・二重書きしないように注意します。
A | B | |
---|---|---|
1 | Desk | 8000 |
2 | Chair | 3000 |
3 | Shelf | 4500 |
以下のプログラムでは、すでに合計が書き込まれているかを確認しながら合計金額を求め、必要に応じて書き込む例を示します。
import openpyxl
# Excelファイルを読み込み、ワークシートを取得
wb = openpyxl.load_workbook("inventory.xlsx")
ws = wb.active
# 合計金額を保持する変数を初期化
total_amount = 0
sum_exist = False # "sum"行が存在するか
row_counter = 1 # 行番号の管理用
# シートの各行を確認して価格を合計
for row_values in ws.iter_rows(values_only=True):
item, cost = row_values[0], None
# インデックスエラーを回避しつつコストを取得
if len(row_values) > 1:
cost = row_values[1]
# もしすでに"Sum"行が存在すれば、合計済みとみなしてループを終了
if item == "Sum":
sum_exist = True
break
# 数値型であれば合計に追加
if isinstance(cost, (int, float)):
total_amount += cost
row_counter += 1
if(sum_exist == False):
# 合計がまだシートに書き込まれていない場合、
# 合計行を1行空けるなどの処理を行いたい場合は行番号を増やす
row_counter += 1
# A列に"Sum"という文字列、B列に合計金額を設定
ws[f"A{row_counter}"] = "Sum"
ws[f"B{row_counter}"] = total_amount
# Excelファイルを上書き保存
wb.save("inventory.xlsx")
コードの詳しい解説
import openpyxl
openpyxlライブラリをインポートし、Excelファイルの操作に備えます。wb = openpyxl.load_workbook("inventory.xlsx")
"inventory.xlsx"
という名前の既存ファイルを読み込みます。ファイル名が異なる場合は、適宜修正してください。ws = wb.active
読み込んだブック内でアクティブなシート(通常は先頭シート)を取得します。total_amount = 0
/row_counter = 1
合計金額を保持する変数と、行番号を管理する変数を用意します。for row_values in ws.iter_rows(values_only=True):
iter_rows
でワークシートの内容を行ごとに取得します。values_only=True
を指定することで、セルオブジェクトではなく値だけを返します。if item == "Sum": break
・もし既に「Sum」と書かれた行が見つかったら、これ以降の行を読み込まずにループを終了します。二重書き込みを防ぐための処理です。if isinstance(cost, (int, float)): total_amount += cost
・コスト列が数値型(intやfloat)の場合のみ合計に加算します。row_counter += 1
行を下に進めるごとにカウンタを加算します。row_counter += 1
合計行の前に1行分を空けたい場合など、必要に応じて追加の処理を行います。ws[f"A{row_counter}"] = "Sum"
/ws[f"B{row_counter}"] = total_amount
f-stringでセルの座標を指定し、合計ラベルと計算結果を書き込みます。wb.save("inventory.xlsx")
同じファイル名で上書き保存します。
この仕組みにより、何度実行しても「Sum」行が見つかった時点でループを終了するため、重複して書き込むことはありません。Excelファイルにテーブルが追加された場合でも、再度プログラムを実行すれば新しい行の合計を計算してくれます。
3.応用:複数ファイルの同時処理
もし複数のExcelファイルに対して同様の処理を行いたい場合は、glob
モジュールを使用すると便利です。*.xlsx
などのパターンを指定して一括検索し、同じ計算ロジックを適用することができます。
import glob
import openpyxl
for file_path in glob.glob("*.xlsx"):
wb = openpyxl.load_workbook(file_path)
ws = wb.active
# ここで上記と同じ合計計算や書き込みを行う
# 合計金額を保持する変数を初期化
total_amount = 0
sum_exist = False # "sum"行が存在するか
row_counter = 1 # 行番号の管理用
# シートの各行を確認して価格を合計
for row_values in ws.iter_rows(values_only=True):
item, cost = row_values[0], None
# インデックスエラーを回避しつつコストを取得
if len(row_values) > 1:
cost = row_values[1]
# もしすでに"Sum"行が存在すれば、合計済みとみなしてループを終了
if item == "Sum":
sum_exist = True
break
# 数値型であれば合計に追加
if isinstance(cost, (int, float)):
total_amount += cost
row_counter += 1
if(sum_exist == False):
# 合計がまだシートに書き込まれていない場合、
# 合計行を1行空けるなどの処理を行いたい場合は行番号を増やす
row_counter += 1
# A列に"Sum"という文字列、B列に合計金額を設定
ws[f"A{row_counter}"] = "Sum"
ws[f"B{row_counter}"] = total_amount
# Excelファイルを上書き保存
wb.save(file_path)
数が増えてもプログラムはほとんど変わりません。ファイル一覧を取得して順番に読み込み、同様の処理をするだけです。
まとめ
Excelの作業をPythonプログラムに任せることで、大幅な時間短縮と正確性の向上が期待できます。特に合計や集計のような単純作業は、スクリプト化してしまえば簡単に自動実行できます。今回のサンプルコードを元に、独自の要件に合わせてロジックや出力形式をカスタマイズしてみてください。膨大な数のExcelファイルを扱う場合や、一定の周期で同じ集計作業を行う場合ほど、プログラムによる自動化のメリットがより大きく感じられるでしょう。