Day 34:Excel自動集計で「人がやっている集計作業」をコードに置き換える
Day 34では、Excelを使った 自動集計 をテーマに、 複数シートに分かれたデータをまとめて集計し、合計・平均・最大・最小 を自動で計算する流れを作っていきます。
キーワードは次の5つです。
- 複数シート
- データ集計
- 合計
- 平均
- 最大・最小
業務現場では、「各店舗ごとの売上シート」「各担当者ごとの実績シート」など、 複数シートに分かれたデータをまとめて集計する場面がよくあります。 それをPythonで自動化できるようになると、毎月・毎週のルーティン作業を大きく減らすことができます。
複数シート構成をイメージする
まずは「店舗ごとの売上シート」を作る
説明を分かりやすくするために、次のような構成のExcelファイルを作ります。
StoreAシート:店舗Aの売上StoreBシート:店舗Bの売上StoreCシート:店舗Cの売上- 後で
Summaryシート:全店舗の集計結果
まずはサンプルデータを作成するコードから始めます。
# day34_setup.py
from openpyxl import Workbook
def create_store_sales_excel():
"""Day 34用の複数シート売上データを作成する関数です。"""
wb = Workbook()
# 店舗Aシート
ws_a = wb.active
ws_a.title = "StoreA"
ws_a["A1"] = "日付"
ws_a["B1"] = "売上"
ws_a["A2"] = "2024-01-01"; ws_a["B2"] = 1200
ws_a["A3"] = "2024-01-02"; ws_a["B3"] = 800
ws_a["A4"] = "2024-01-03"; ws_a["B4"] = 1500
# 店舗Bシート
ws_b = wb.create_sheet(title="StoreB")
ws_b["A1"] = "日付"
ws_b["B1"] = "売上"
ws_b["A2"] = "2024-01-01"; ws_b["B2"] = 900
ws_b["A3"] = "2024-01-02"; ws_b["B3"] = 1100
ws_b["A4"] = "2024-01-03"; ws_b["B4"] = 700
# 店舗Cシート
ws_c = wb.create_sheet(title="StoreC")
ws_c["A1"] = "日付"
ws_c["B1"] = "売上"
ws_c["A2"] = "2024-01-01"; ws_c["B2"] = 500
ws_c["A3"] = "2024-01-02"; ws_c["B3"] = 1300
ws_c["A4"] = "2024-01-03"; ws_c["B4"] = 900
wb.save("stores_sales.xlsx")
print("stores_sales.xlsx を作成しました。")
if __name__ == "__main__":
create_store_sales_excel()
Pythonこのファイルをもとに、複数シートのデータをまとめて集計していきます。
複数シートからデータを集計する基本方針
「各シートの売上列を読み取って、まとめて計算する」
やりたいことを分解すると、次のようになります。
- Excelファイルを読み込む
- 対象となるシート(
StoreA・StoreB・StoreC)を順番に処理する - 各シートの売上列(B列)を読み取る
- すべての売上データを1つのリストに集める
- 合計・平均・最大・最小を計算する
- 結果を
Summaryシートに書き込む
この流れをコードに落とし込んでいきます。
データ集計:複数シートから売上を集める
from openpyxl import load_workbook
def collect_sales_from_sheets(filename="stores_sales.xlsx", sheet_names=None):
"""複数シートから売上データを集める関数です。"""
wb = load_workbook(filename)
# 対象シート名が指定されていなければ、デフォルトで StoreA/B/C を使います。
if sheet_names is None:
sheet_names = ["StoreA", "StoreB", "StoreC"]
all_sales = [] # 全店舗の売上を格納するリストです。
for name in sheet_names:
ws = wb[name]
print(f"シート {name} の売上を読み込みます。")
# 2行目以降のB列(売上)を読み取ります。
for row in range(2, 5): # 今回は2〜4行目にデータがある前提です。
value = ws.cell(row=row, column=2).value # B列
if isinstance(value, (int, float)):
all_sales.append(value)
print(f" 行{row}: 売上={value}")
return all_sales
Pythonここでのポイントは、
sheet_namesで対象シートを指定できるようにしていること- 各シートのB列(売上)をループで読み取り、
all_salesに集めていること - 「複数シートのデータを1つのリストにまとめる」ことで、後の集計処理をシンプルにしていること
です。
合計・平均・最大・最小を計算する
Pythonの標準機能で集計する
集めた売上データは、Pythonの標準関数で簡単に集計できます。
def calculate_statistics(values):
"""売上リストから合計・平均・最大・最小を計算する関数です。"""
if not values:
return {
"sum": 0,
"avg": 0,
"max": 0,
"min": 0,
}
total = sum(values)
avg = total / len(values)
max_value = max(values)
min_value = min(values)
print("=== 集計結果 ===")
print(f"合計: {total}")
print(f"平均: {avg}")
print(f"最大: {max_value}")
print(f"最小: {min_value}")
return {
"sum": total,
"avg": avg,
"max": max_value,
"min": min_value,
}
Pythonここでのポイントは、
sum()・max()・min()といった標準関数を使っていること- 平均は
合計 ÷ 件数で計算していること - 結果を辞書(
dict)にまとめて返しているため、後で扱いやすいこと
です。
Summaryシートに集計結果を書き込む
新しいシートを作って結果を整理する
from openpyxl import load_workbook
def write_summary_sheet(stats, filename="stores_sales.xlsx"):
"""集計結果を Summary シートに書き込む関数です。"""
wb = load_workbook(filename)
# 既に Summary シートがある場合は再利用し、なければ作成します。
if "Summary" in wb.sheetnames:
ws_summary = wb["Summary"]
else:
ws_summary = wb.create_sheet(title="Summary")
# ヘッダー行
ws_summary["A1"] = "項目"
ws_summary["B1"] = "値"
# 集計結果を書き込みます。
ws_summary["A2"] = "合計"
ws_summary["B2"] = stats["sum"]
ws_summary["A3"] = "平均"
ws_summary["B3"] = stats["avg"]
ws_summary["A4"] = "最大"
ws_summary["B4"] = stats["max"]
ws_summary["A5"] = "最小"
ws_summary["B5"] = stats["min"]
wb.save("stores_sales_with_summary.xlsx")
print("stores_sales_with_summary.xlsx に Summary シートを書き込みました。")
Pythonここでのポイントは、
Summaryという新しいシートを作り、集計結果だけを整理していること- 「項目」と「値」という2列構成で、シンプルに結果を表示していること
- 元のファイルとは別名で保存しているため、元データを壊さないこと
です。
一連の流れをまとめる:Excel自動集計スクリプト
Day 34の完成テンプレート
# day34_excel_aggregate.py
from openpyxl import Workbook, load_workbook
def create_store_sales_excel():
wb = Workbook()
ws_a = wb.active
ws_a.title = "StoreA"
ws_a["A1"] = "日付"; ws_a["B1"] = "売上"
ws_a["A2"] = "2024-01-01"; ws_a["B2"] = 1200
ws_a["A3"] = "2024-01-02"; ws_a["B3"] = 800
ws_a["A4"] = "2024-01-03"; ws_a["B4"] = 1500
ws_b = wb.create_sheet(title="StoreB")
ws_b["A1"] = "日付"; ws_b["B1"] = "売上"
ws_b["A2"] = "2024-01-01"; ws_b["B2"] = 900
ws_b["A3"] = "2024-01-02"; ws_b["B3"] = 1100
ws_b["A4"] = "2024-01-03"; ws_b["B4"] = 700
ws_c = wb.create_sheet(title="StoreC")
ws_c["A1"] = "日付"; ws_c["B1"] = "売上"
ws_c["A2"] = "2024-01-01"; ws_c["B2"] = 500
ws_c["A3"] = "2024-01-02"; ws_c["B3"] = 1300
ws_c["A4"] = "2024-01-03"; ws_c["B4"] = 900
wb.save("stores_sales.xlsx")
print("stores_sales.xlsx を作成しました。")
def collect_sales_from_sheets(filename="stores_sales.xlsx", sheet_names=None):
wb = load_workbook(filename)
if sheet_names is None:
sheet_names = ["StoreA", "StoreB", "StoreC"]
all_sales = []
for name in sheet_names:
ws = wb[name]
print(f"シート {name} の売上を読み込みます。")
for row in range(2, 5):
value = ws.cell(row=row, column=2).value
if isinstance(value, (int, float)):
all_sales.append(value)
print(f" 行{row}: 売上={value}")
return all_sales
def calculate_statistics(values):
if not values:
return {"sum": 0, "avg": 0, "max": 0, "min": 0}
total = sum(values)
avg = total / len(values)
max_value = max(values)
min_value = min(values)
print("=== 集計結果 ===")
print(f"合計: {total}")
print(f"平均: {avg}")
print(f"最大: {max_value}")
print(f"最小: {min_value}")
return {"sum": total, "avg": avg, "max": max_value, "min": min_value}
def write_summary_sheet(stats, filename="stores_sales.xlsx"):
wb = load_workbook(filename)
if "Summary" in wb.sheetnames:
ws_summary = wb["Summary"]
else:
ws_summary = wb.create_sheet(title="Summary")
ws_summary["A1"] = "項目"
ws_summary["B1"] = "値"
ws_summary["A2"] = "合計"; ws_summary["B2"] = stats["sum"]
ws_summary["A3"] = "平均"; ws_summary["B3"] = stats["avg"]
ws_summary["A4"] = "最大"; ws_summary["B4"] = stats["max"]
ws_summary["A5"] = "最小"; ws_summary["B5"] = stats["min"]
wb.save("stores_sales_with_summary.xlsx")
print("stores_sales_with_summary.xlsx に Summary シートを書き込みました。")
def main():
create_store_sales_excel()
sales = collect_sales_from_sheets()
stats = calculate_statistics(sales)
write_summary_sheet(stats)
if __name__ == "__main__":
main()
Pythonこのスクリプトを実行すると、
stores_sales.xlsxに店舗ごとの売上データが作成され- 3店舗分の売上をまとめて集計し
- 集計結果を
Summaryシートに書き込んだstores_sales_with_summary.xlsxが生成されます。
Day 34のまとめ
Day 34では、Excel自動集計として、
- 複数シート(StoreA/B/C)の構成を作り、店舗ごとのデータを持たせる方法
- 複数シートから売上列を読み取り、1つのリストにまとめて集計する考え方
- 合計・平均・最大・最小をPythonの標準関数で計算する方法
- 集計結果を
Summaryシートに整理して書き込むことで、「人に見せられる集計表」を自動生成する流れ
をステップバイステップで体験していただきました。
ここまで来ると、Excelを「人が毎回開いて集計するもの」から、 「Pythonが自動で集計してくれるレポートの土台」として扱う感覚が育ってきます。 次のDayでは、さらに業務シナリオに近づけて、 より複雑な集計や条件付きの処理にも踏み込んでいきます。
