基礎から学ぶPython入門 90日コース | 業務自動化 - Day 34:Excel自動集計

Python 90日で身につけるPython
スポンサーリンク
スポンサーリンク

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

このファイルをもとに、複数シートのデータをまとめて集計していきます。

複数シートからデータを集計する基本方針

「各シートの売上列を読み取って、まとめて計算する」

やりたいことを分解すると、次のようになります。

  1. Excelファイルを読み込む
  2. 対象となるシート(StoreAStoreBStoreC)を順番に処理する
  3. 各シートの売上列(B列)を読み取る
  4. すべての売上データを1つのリストに集める
  5. 合計・平均・最大・最小を計算する
  6. 結果を 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

このスクリプトを実行すると、

  1. stores_sales.xlsx に店舗ごとの売上データが作成され
  2. 3店舗分の売上をまとめて集計し
  3. 集計結果を Summary シートに書き込んだ stores_sales_with_summary.xlsx が生成されます。

Day 34のまとめ

Day 34では、Excel自動集計として、

  • 複数シート(StoreA/B/C)の構成を作り、店舗ごとのデータを持たせる方法
  • 複数シートから売上列を読み取り、1つのリストにまとめて集計する考え方
  • 合計・平均・最大・最小をPythonの標準関数で計算する方法
  • 集計結果を Summary シートに整理して書き込むことで、「人に見せられる集計表」を自動生成する流れ

をステップバイステップで体験していただきました。

ここまで来ると、Excelを「人が毎回開いて集計するもの」から、 「Pythonが自動で集計してくれるレポートの土台」として扱う感覚が育ってきます。 次のDayでは、さらに業務シナリオに近づけて、 より複雑な集計や条件付きの処理にも踏み込んでいきます。

タイトルとURLをコピーしました