コース2:Excel業務効率化

openpyxlとpandasを使い、Excelファイルの読み書き・データ集計・自動レポート生成を実装します。月次売上集計・複数ファイルの一括処理・グラフ付きレポートまで、その日から業務で使える題材だけを取り上げました。

レッスン 1

openpyxlの基本 — Excelを開く・読む・書く

業務シーン

毎月送られてくる売上Excelを開き、合計を別シートに転記する作業。1ファイルなら数分ですが、ファイルが20個あれば1時間以上。これをPythonに任せる第一歩が openpyxl です。

インストール

bash
pip install openpyxl

Excelを読む

python
from openpyxl import load_workbook

# ファイルを開く
wb = load_workbook("sales.xlsx")

# シートを取得
ws = wb["売上明細"]      # シート名で取得
# ws = wb.active            # 先頭シートを取得

# セルの値を取得
print(ws["A1"].value)
print(ws.cell(row=1, column=1).value)   # 同じ意味

# 全行を順に読む
for row in ws.iter_rows(min_row=2, values_only=True):
    print(row)
    # → ('2026-01-05', 'A001', 'サクラ商事', 12, 1580)

Excelに書き込んで保存

python
from openpyxl import Workbook

wb = Workbook()
ws = wb.active
ws.title = "集計結果"

ws["A1"] = "月"
ws["B1"] = "売上合計"
ws.append(["2026年1月", 3850000])
ws.append(["2026年2月", 4210000])

wb.save("summary.xlsx")
print("保存しました。")
注意

対象のExcelファイルを開いたままPythonで保存しようとするとエラーになります。必ず閉じてから実行してください。

レッスン 2

セル・行・列の操作と書式設定

セル範囲の取得

python
# A1:C3 の範囲を2次元で取り出す
for row in ws["A1:C3"]:
    for cell in row:
        print(cell.coordinate, cell.value)

# 列全体(A列)を取得
for cell in ws["A"]:
    print(cell.value)

# 最終行 / 最終列
print(ws.max_row, ws.max_column)

書式設定 — 太字・色・罫線・列幅

python
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side

# 見出し行を装飾
header_font = Font(name="Yu Gothic", bold=True, color="FFFFFF")
header_fill = PatternFill("solid", fgColor="7C3AED")
center = Alignment(horizontal="center", vertical="center")
thin = Side(style="thin", color="BFBFBF")
border = Border(left=thin, right=thin, top=thin, bottom=thin)

for cell in ws[1]:    # 1行目
    cell.font = header_font
    cell.fill = header_fill
    cell.alignment = center
    cell.border = border

# 列幅の指定
ws.column_dimensions["A"].width = 14
ws.column_dimensions["B"].width = 18

# 数値表示形式(3桁区切り)
for cell in ws["B"][1:]:
    cell.number_format = "#,##0"
学習のポイント

色は RRGGBB のHEX文字列(先頭の # は付けない)で指定します。本サイトのテーマ色は 7C3AED(紫)と 2563EB(青)です。

レッスン 3 ・ 中核レッスン

月次売上集計の自動化

業務背景

毎月初に、支店から送られてくる売上明細Excelを開き、月次合計と前月比を集計して上司に提出する作業——この一連の作業を、Pythonで完全に自動化します。本レッスンが終わる頃には、ファイル名を変えるだけで毎月使い回せるスクリプトが手元に残ります。

入力ファイルの想定

sales_2026.xlsx」というファイルに、以下のような明細データが入っているとします。

日付商品コード取引先数量単価
2026-01-05A001サクラ商事121,580
2026-01-12B003あおぞら工業58,200
2026-02-03A001みどり物産201,580
...............

完成スクリプト(openpyxlのみで実装)

下記のコードを monthly_summary.py として保存し、同じフォルダに sales_2026.xlsx を置いて実行してください。

python
"""
月次売上集計スクリプト
- 入力: sales_2026.xlsx (売上明細シート)
- 出力: summary_2026.xlsx (月次集計シート + 書式設定)
"""
from openpyxl import load_workbook, Workbook
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from collections import defaultdict
from datetime import datetime

INPUT  = "sales_2026.xlsx"
OUTPUT = "summary_2026.xlsx"

# --- 1. 明細を読み込み、月ごとに合計する -----------------------------
def aggregate_monthly(path):
    wb = load_workbook(path, data_only=True)
    ws = wb.active

    monthly = defaultdict(lambda: {"amount": 0, "count": 0})

    for row in ws.iter_rows(min_row=2, values_only=True):
        date, code, client, qty, unit_price = row[:5]
        if not date or not qty or not unit_price:
            continue   # 空行はスキップ
        if isinstance(date, str):
            date = datetime.strptime(date, "%Y-%m-%d")
        key = date.strftime("%Y-%m")
        monthly[key]["amount"] += qty * unit_price
        monthly[key]["count"] += 1

    return dict(sorted(monthly.items()))

# --- 2. 前月比を計算 --------------------------------------------
def attach_mom(monthly):
    prev = None
    result = []
    for month, stat in monthly.items():
        mom = None if prev is None else stat["amount"] / prev - 1
        result.append({
            "month":  month,
            "amount": stat["amount"],
            "count":  stat["count"],
            "mom":    mom,
        })
        prev = stat["amount"]
    return result

# --- 3. Excelに整形して書き出し ---------------------------------
def write_summary(rows, path):
    wb = Workbook()
    ws = wb.active
    ws.title = "月次集計"
    ws.append(["月", "売上合計", "明細件数", "前月比"])

    for r in rows:
        ws.append([
            r["month"],
            r["amount"],
            r["count"],
            None if r["mom"] is None else round(r["mom"], 4),
        ])

    # 書式設定
    header_font = Font(bold=True, color="FFFFFF")
    header_fill = PatternFill("solid", fgColor="7C3AED")
    center = Alignment(horizontal="center")
    thin = Side(style="thin", color="BFBFBF")
    border = Border(left=thin, right=thin, top=thin, bottom=thin)

    for cell in ws[1]:
        cell.font, cell.fill, cell.alignment = header_font, header_fill, center

    for row in ws.iter_rows(min_row=2, max_col=4):
        for cell in row:
            cell.border = border
        row[1].number_format = "#,##0"     # 売上合計
        row[3].number_format = "0.0%"      # 前月比

    for col, w in zip("ABCD", [12, 16, 12, 12]):
        ws.column_dimensions[col].width = w

    wb.save(path)

# --- 4. 実行エントリポイント ------------------------------------
if __name__ == "__main__":
    monthly = aggregate_monthly(INPUT)
    rows    = attach_mom(monthly)
    write_summary(rows, OUTPUT)
    print(f"{len(rows)}か月分を {OUTPUT} に出力しました。")

実行結果

月次売上集計の出力例(Excel)
生成された summary_2026.xlsx の例:月・売上合計・明細件数・前月比が整形済みの形で並ぶ。

コードを3つに分けた理由

このスクリプトは「集計する」「前月比を付ける」「Excelに書く」を別の関数に分けてあります。理由は2つあります。

  1. 業務ルールが変わったとき、書き換える場所がすぐ分かる。たとえば「税込で集計したい」となったら aggregate_monthly だけ直せばよい。
  2. テストしやすい。本物のExcelを用意しなくても、関数単位で動作確認ができる。
Copilotへの質問例

Windows Copilotにこの題材を投げる場合、最初の依頼はこのくらい具体的に書きます。

「Excelの月次売上データを自動集計するPythonスクリプトを作成してください。
入力ファイル名は sales_2026.xlsx、シートには日付・商品コード・取引先・数量・単価の5列があります。
月ごとに売上合計と明細件数を計算し、前月比も付けて、新しいExcelファイル summary_2026.xlsx に書き出してください。
使用するライブラリは openpyxl のみ、ヘッダ行は紫(#7C3AED)で塗り、売上合計は3桁区切り、前月比はパーセント表記でお願いします。」
  • 本レッスンの学習チェックリスト
  • iter_rows(values_only=True) で1行ずつ値を取り出せる
  • defaultdict を使い、月ごとに合計を加算できる
  • 集計・計算・出力を別関数に分け、責任を分けて書ける
  • ヘッダの色・列幅・数値書式をopenpyxlで指定できる
  • Copilotに渡すプロンプトを、入力・出力・条件の順で書ける
演習 ・ コード判定対応

取引先別の年間集計シートを追加してみよう

上のスクリプトを拡張し、出力Excelに「取引先別年間集計」シートを追加してください。シートには 取引先名・年間売上合計・取引件数 の3列を、年間売上の降順で並べます。

python
def aggregate_by_client(path):
    wb = load_workbook(path, data_only=True)
    ws = wb.active
    by_client = defaultdict(lambda: {"amount": 0, "count": 0})
    for row in ws.iter_rows(min_row=2, values_only=True):
        _, _, client, qty, unit = row[:5]
        if not client: continue
        by_client[client]["amount"] += qty * unit
        by_client[client]["count"] += 1
    # 売上の降順に並べ替えて返す
    return sorted(by_client.items(), key=lambda x: -x[1]["amount"])

# write_summary 関数の中で、シート追加処理を加える:
ws2 = wb.create_sheet("取引先別年間集計")
ws2.append(["取引先", "年間売上", "取引件数"])
for name, stat in aggregate_by_client(INPUT):
    ws2.append([name, stat["amount"], stat["count"]])
レッスン 4

pandasで大規模データ集計とピボット

業務シーン

明細が1万行を超える大規模データを「商品×月」のピボット集計したい。openpyxlだとループが必要な処理も、pandasを使えば数行で書けます。

インストール

bash
pip install pandas openpyxl

Excelを読み込んで集計する

python
import pandas as pd

# Excel全体をDataFrameとして読み込む
df = pd.read_excel("sales_2026.xlsx")

# 売上金額の列を作る
df["amount"] = df["数量"] * df["単価"]

# 月列を作る
df["月"] = pd.to_datetime(df["日付"]).dt.to_period("M").astype(str)

# 月ごとの合計
monthly = df.groupby("月")["amount"].sum().reset_index()
print(monthly)

ピボットテーブル — 商品×月のクロス集計

python
pivot = pd.pivot_table(
    df,
    index="商品コード",
    columns="月",
    values="amount",
    aggfunc="sum",
    fill_value=0,
    margins=True,        # 合計行と合計列を追加
    margins_name="合計",
)

# 結果をExcelに書き出す
pivot.to_excel("pivot_summary.xlsx")
print("ピボット集計を出力しました。")
学習のポイント

Excelの「ピボットテーブル」と同じ機能を、ボタン操作ではなくコードで定義します。コードなら毎月使い回せて、誰が実行しても同じ結果になる、というのが業務上の大きな利点です。

レッスン 5

複数Excelファイルの一括処理

業務シーン

支店ごとに送られてくる20個のExcelファイルを、1つの全社版にまとめたい。手作業ではコピー&ペーストの繰り返しですが、Pythonなら30秒で終わります。

フォルダ内のExcelをすべて結合する

python
import pandas as pd
from pathlib import Path

folder = Path("./branches")
all_dfs = []

for file in folder.glob("*.xlsx"):
    df = pd.read_excel(file)
    df["支店"] = file.stem     # ファイル名から支店名を付与
    all_dfs.append(df)
    print(f"読込: {file.name} ({len(df)}行)")

merged = pd.concat(all_dfs, ignore_index=True)
merged.to_excel("all_branches.xlsx", index=False)
print(f"合計 {len(merged)} 行を1ファイルに統合しました。")
注意

支店ごとにExcelの列順や列名が違うと結合できません。事前に「列名は揃える」というルールを支店側にも共有しておくと、自動化がぐっと安定します。

レッスン 6

グラフ付き自動レポートの生成

業務シーン

集計表だけでなく、棒グラフ付きでExcelに出したい。openpyxlの BarChart を使えば、グラフもPythonで埋め込めます。

月次売上の棒グラフを埋め込む

python
from openpyxl import Workbook
from openpyxl.chart import BarChart, Reference

wb = Workbook()
ws = wb.active
ws.title = "月次集計"

# データ書き込み
ws.append(["月", "売上合計"])
data = [
    ("2026-01", 3850000),
    ("2026-02", 4210000),
    ("2026-03", 3990000),
    ("2026-04", 4520000),
]
for row in data:
    ws.append(row)

# 棒グラフを作成
chart = BarChart()
chart.title = "月次売上推移"
chart.y_axis.title = "売上(円)"
chart.x_axis.title = "月"

values = Reference(ws, min_col=2, min_row=1, max_row=5)
cats   = Reference(ws, min_col=1, min_row=2, max_row=5)
chart.add_data(values, titles_from_data=True)
chart.set_categories(cats)

ws.add_chart(chart, "D2")    # D2セルにグラフを配置

wb.save("report_with_chart.xlsx")
  • コース2 修了チェックリスト
  • openpyxlでExcelを読み書きできる
  • 月次集計のスクリプトを自分で組み立てられる
  • pandasのgroupbyとpivot_tableで集計できる
  • フォルダ内の複数Excelを一括結合できる
  • openpyxlのBarChartでグラフ付きレポートを生成できる
次のステップ

ここまでで「Pythonで業務を自動化する」ための土台ができました。コース3「Windows Copilotで自動化」 では、Copilotにコードを書いてもらいながら、自分の業務に最短で適用する方法を学びます。