処理は、Excel の中ではなく Python の側に置く。
2-03: 土台を据える ── SQLite・PostgreSQL・pgvector・DuckDB・Polars でデータの置き場を据えた。この章では、その上のデータを実際に動かす。Excel と Word に埋まったマクロ・VBA・グラフ・ピボットを Python に出し、人が触る画面が要るところには Flet を被せる。
要るのは、書く能力ではなく使う能力だ
これまでの常識では、プログラミングを学ぶとは、文法を覚え、アルゴリズムを設計し、コードを書けるようになることだった。
いまは違う。何を処理したいかを言葉にし、AI にコードを書いてもらい、実行し、結果を確かめる。要るのは 使う能力 だ。
Excel の関数を覚える時間と、Python を AI に書いてもらえるようになる時間を比べれば、後者のほうがはるかに短い。そして Excel の関数は Excel の中で効くが、Python はあらゆるデータに効く。
書く能力ではなく、使う能力。これが新しいリテラシーである。
コードを書く能力は要らない。読める能力で足りる。読めれば、返ってきたコードが正しそうかどうかは判断できる。エラーが出たら、そのエラー文をそのまま貼って渡せば、原因と修正版が返る。エラーは終わりではなく、次の指示の入力だ。
(日本語で説明)"] AI(("AI")) Code["Python コード"] Run["実行"] Out["結果
確認"] Err["エラー文"] Want -->|頼む| AI AI -->|書く| Code Code --> Run Run -->|成功| Out Run -->|失敗| Err Err -->|貼り付け| AI classDef good fill:#e8f5e9,stroke:#7a9a6d,color:#3a4d34 classDef bad fill:#fef3e7,stroke:#c89559,color:#5a3f1a class Want,Out good class AI,Code,Err bad
頼むときのこつは三つだ。入力と出力を明示する。一つずつ頼む。結果を見て直す。「orders.xlsx を読んで、商品ごとの売上合計を summary.json に書き出して」と、入口と出口の形が決まっていれば、AI は迷わない。
Excel と Word に埋まった処理を、Python に出す
自立編で Office から離れるとき、最後まで残る問題が、*Excel と Word の中に埋まった業務ロジック* だ。マクロ、VBA、グラフ、ピボット ── この四つを Python に外部化する。ここが最初の一手になる。
VBA の中身は、たいてい「セルからデータを読む → 何か計算する → 別のセルに書く」の組み合わせだ。これは Polars で素直に書き換えられる。
- Excel の VBA エディタ(Alt + F11)を開く
- モジュールのコードをコピーして AI に渡す
- 「これを Polars + Python に書き換えて」と頼む
- 返ってきたコードを JupyterLab のセルに貼って Shift+Enter
import polars as pl
df = pl.read_excel("orders.xlsx", sheet_name="raw")
result = (
df.filter(pl.col("status") == "確定")
.group_by("customer")
.agg(total=(pl.col("qty") * pl.col("price")).sum())
.sort("total", descending=True)
)
result.write_excel("monthly_summary.xlsx")
Excel はやめなくてよい。Polars は .xlsx を直接読み書きし、書式を保ったまま編集したいときは openpyxl を使う。原則は一つだけある ── .xlsx のまま扱うことだ。CSV に落とすと、書式も数式も体裁も一緒に落ちる。
Word と PowerPoint にも VBA はいる
VBA は Excel だけの話ではない。Word にも同じように埋まっている。差し込み印刷の自動化、テンプレートからの文書生成、書式の一括変換、配ったフォームの回収と集計 ── どれも Python に出せる。
- 差し込み印刷・テンプレート文書生成 →
python-docx+ Jinja2(宛先は Polars で読む顧客マスタ) - 書式の一括変換 →
python-docxで全文を走査して置換する - 配布フォームの集計 → 各 Word を
python-docxで読み、Polars に集約する
PowerPoint のマクロも同じだ。python-pptx で外に出せる。
先に出すほど、後が軽い
VBA は、Excel 互換の表計算ソフトではそのまま動かない。Office からの乗り換えで一番大きな問題は、ここにある。処理を Python に出してしまえば、ファイルの側は「データ + レイアウト」だけになり、2-07: 文書を取り戻す ── 読む物は adoc、触る表は格子、刷る紙はテンプレート の持ち方にそのまま乗る。
外に出す理由は、乗り換えだけではない。
- Python のコードはテキストなので、Git で履歴を持ち、テストし、レビューできる
- Office の版が上がってもコードはそのまま動く。Python 3 のコードは、この先も長く読める
そして、守りの理由がある。*VBA は、2022 年までメール添付によるマルウェアの主な入口だった*。日本で最も広がった Emotet は、マクロ付きの Excel や Word を添付し、「コンテンツの有効化」を押させて感染した(JPCERT/CC、2022 年 2 月の注意喚起)。 Microsoft は 2022 年 7 月から、インターネットから届いたファイルのマクロを Windows の Office で既定で止め、添付のマクロを使う攻撃は約 66% 減った(Proofpoint、2022 年 7 月)。だが止まるのは、外から届いたファイルだけだ。業務ロジックを VBA に置いている限り、社内ではマクロを有効にし続け、「有効化」を押す習慣が残る。処理を Python に出せば、マクロを有効にする理由そのものが無くなる。
「VBA を Python に書き換えるのは大変では」と思うかもしれない。渡し方はコピーと貼り付けだけだ。
JupyterLab を入れる ── 標準は uv、科学計算は Miniforge
Python を使うには実行環境が要る。事務の仕事に最も合う入口は JupyterLab だ。ブラウザで動く「Python のスプレッドシート」で、セルに Python を書いて Shift+Enter、その場で結果が出る。Excel のセルに =SUM(A1:A100) と書いて Enter を押すのと同じ感覚だ。
Excel のピボットテーブルとの違いは、残るものにある。
- 実行手順がコード数行として残る ── 翌月は再実行するだけで済む
- 「なぜこの計算をしたか」を Markdown セルで隣に書ける ── 業務知識がノートに残る
- グラフもセルの中に描ける(matplotlib / Altair)
- Excel の行数の上限(2-03)が無い
- ノートブック(
.ipynb)として保存し、Git で履歴を持てる - 担当者が替わっても、ノートブックを開けば続きから作業できる
Python 本体とライブラリの入れ方は、用途で二択だ。
| 入れ方 | 適している用途 | 特徴 |
|---|---|---|
uv(標準) |
日常の Python、CLI ツール、Web、業務スクリプト、Polars / FastAPI / 文書まわり | 圧倒的に速い。Rust 製で、PyPI を素直に扱う。uv tool install で配れる |
| Miniforge(DS/科学計算) | データ分析、機械学習、画像処理、科学計算、GPU(numpy / scipy / scikit-learn / pytorch / tensorflow / gdal など) |
conda-forge を既定で使う FLOSS 版 conda。複雑な C/C++/Fortran 依存をコンパイル済みバイナリで配る |
まず uv から入れる。ほとんどの場面はこれで足りる。
# Mac / Linux:公式インストーラ(Windows は PowerShell の一行)
curl -LsSf https://astral.sh/uv/install.sh | sh
uv init tools && cd tools # 仕事用の Python の環境を一つ作る
uv add jupyterlab polars altair # 入れる。以降の章の道具も、ここに足す
uv run jupyter lab # 開く
ブラウザが開き、新しいノートブックを作って、セルに書いて Shift+Enter。ここまでだ。この環境が、この連載の Python の置き場になる。2-03 の DuckDB も、ここに足す。
uv で行き詰まるのは、科学計算まわりが多い。numpy / scipy / pytorch /
tensorflow のビルドが手元で失敗する(BLAS / LAPACK / CUDA との結合)、GIS 系
(gdal、rasterio)や生物系で C/C++ 依存が膨大になる、GPU の深層学習で CUDA の版を揃える必要がある ── このときは Miniforge に切り替える。Anaconda の商用条項に縛られず、
conda の依存解決の強さだけを使える。
# Miniforge(完全 FLOSS)
curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh
bash Miniforge3-*.sh
# 以後はこれで環境を作る
conda create -n ds jupyterlab polars numpy scipy scikit-learn
conda activate ds
迷ったら uv。
uvのエラーが続いたら Miniforge。どちらも AI が同じように扱える ── 「uvで入れて」「condaで入れて」と頼めば、それぞれの作法でコマンドが返る。
ピボットと VLOOKUP を、Polars のコードにする
JupyterLab に Polars を組み合わせると、Excel でピボットテーブル・VLOOKUP・IF・フィルタでやっていた操作が、そのままコードになる。
| Excel で | Polars で |
|---|---|
| ピボットテーブル(行・列・値) | df.pivot(...) または df.group_by(...).agg(...) |
| VLOOKUP / XLOOKUP | df.join(other, on="...") |
| IF / IFS(計算列) | df.with_columns(...) + pl.when().then().otherwise() |
| フィルタ | df.filter(...) |
| ソート | df.sort(...) |
| 重複削除 | df.unique(...) |
| 累積合計・前月比 | ウィンドウ関数(cum_sum、shift、pct_change) |
月別商品別のクロス集計は、Excel なら行に「商品」、列に「月」、値に「売上」をマウスでドラッグして数分。翌月はもう一度同じマウスを動かす。Polars なら二行だ。
df = pl.read_excel("orders.xlsx")
df.pivot(values="price", index="item", on="month", aggregate_function="sum")
セルで Shift+Enter、下にクロス集計表が出る。翌月は再実行するだけだ。 VLOOKUP の置き換えも同じ形になる。
orders = pl.read_excel("orders.xlsx")
products = pl.read_excel("products.xlsx")
orders.join(products, on="item_id", how="left")
複数の列で結合するときも on=["item_id", "date"] と並べるだけだ。条件で計算列を足すのも、上から順に when().then() を足していく形になる。ネストした IF を数えながら書く必要は無くなる。
文法は覚えなくてよい。「orders.xlsx を読んで、商品ごとの月別売上を集計、上位 10 商品だけを取り出して、前月比のパーセントも付けて」と日本語で頼めば、Polars のコードが返る。
グラフは matplotlib と Altair で描く
可視化に使うライブラリは二つある。
matplotlib は、何でも描ける事実上の標準だ。折れ線・棒・散布・ヒストグラム・ヒートマップ・3D・地図・出版品質の図まで、二十年を超える蓄積がある(初版は 2003 年)。機能は最大で、書き方は長い。
Altair は、「この列を X 軸、この列を Y 軸、この列で色分け」と宣言的に書く。 Vega-Lite が土台で、出力はそのままインタラクティブな HTML になる。ズーム、ホバー、選択が標準で付いてくる。
import altair as alt
import polars as pl
df = pl.read_excel("orders.xlsx")
alt.Chart(df).mark_bar().encode(
x="item",
y="qty:Q",
color="month",
)
JupyterLab のセルで Shift+Enter、下に積み上げ棒グラフが出る。Excel で同じ図を作るなら、ピボット、グラフ、凡例の調整で数分かかる。ここでは六行だ。
どちらのライブラリも、人が文法を覚えるのは骨が折れる。だから覚えない。「orders.xlsx の月別売上を、商品ごとに色分けした積み上げ棒グラフで。凡例は右上、 Y 軸は 100 万単位で」と頼み、返ってきた図を見て「色をもっと落ち着いた色に」と返す。これで済む。
Excel のグラフ機能との違いは、毎月の再生成と再現性に出る。マウス操作は記録が残らず、翌月もう一度同じ手を動かすことになる。コードは記録として残り、Git に入り、
python report.py で PNG も SVG も HTML も出る。
人のための入出力を、基幹から剥がす
ここからが、この章の要になる。
基幹システム(ERP、業務システム、データウェアハウス)は、組織で共有するデータの 記録元 として残す。そこは触らない。しかし、次の四つは記録元の役目ではない。
- データを入力するための画面
- レポートとダッシュボードを生成する仕組み
- 集計を作る仕組み
- 帳票・請求書・通知メールを出す仕組み
これらは 人にとっての入出力 だ。基幹から剥がして、手元の JupyterLab と Python と SQLite に降ろす。基幹とは、API か JSON / Parquet のエクスポートで読み書きするだけの関係になる。
負荷の面からも、分けたほうが速い
基幹システムは記録元として最適化されている。小さく速いトランザクション、インデックスで一行を引く処理が中心だ(OLTP)。一方、帳票・グラフ・集計は真逆の性質を持つ。数百万行をスキャンして集約し、複数のテーブルを結合する、長く重いクエリだ(OLAP)。
この二つを同じシステムの上で動かすと、こうなる。
- 通常の業務処理と CPU・メモリを取り合う
- ロック競合でトランザクションが遅くなる
- 月末の帳票実行で営業システムが固まる ── こういう事故が起きる
必要なデータを基幹から定期的に SQLite / Parquet にエクスポートし(または API で読み出し)、手元で集計と帳票化をすれば、基幹には読み出しだけの軽い負荷しか掛からない。集計は手元で何度でも回せる。集計は Polars と DuckDB の仕事だ(2-03)。
*人のための入出力を手元に降ろすことは、生産性の話であると同時に、基幹を守る負荷分離でもある。* この分離があるから、2-12: API を作る ── FastAPI で基幹のロジックを出す の基幹書き換えは、記録元だけを相手にする小さな仕事になる。
手元に降りてくるもの
剥がすと、組織が抱えていた複雑さの一部が要らなくなる。
- 「営業データを月別商品別に見たい」→ IT 部門に依頼 → BI ツールでレポート → 数日後にメール、だった作業が、JupyterLab の一つのセルになる
- 顧客マスタを更新するための ERP 画面と権限管理が、SQLite + Python に降りる
- ダッシュボードのための BI ツールのライセンスと専門家の代わりに、Altair が立つ。自分で書けて、HTML で配れる
- 月次レポート用のレポーティングサーバーが、cron + Python スクリプトに降りる
- BI 用のデータマートが、SQLite / Parquet のファイルに降りる
請求書の発行も、同じ形で降りる
会計ソフトや ERP の画面で出していた請求書も、同じ形をしている。会計そのもの (仕訳・税務)は会計ソフトに残し、降ろすのは発行の側だ。
- 顧客マスタ・取引データ → SQLite(2-03)
- 請求書の様式 → adoc / HTML(2-07)
- 生成スクリプト → Python + AI(本章)、PDF 化は pandoc / weasyprint
百通の請求書 PDF を月末に一括生成し、メール送信まで Python で書ける。cron で日時を決めて回す。データは手元に残る。見積書、契約書、月次レポート、商品カタログ、納品書 ── 同じ構造で書けるものは、すべて基幹から手元へ降りる。
個人の生産性向上は、組織の単純化に直結する。一人 + AI が、これまで基幹システムと専門部門で支えていた仕事を、順に引き取っていく。
道具は CLI から始め、Flet へ伸ばす
手元に降ろした処理を、人が使う道具の形にする。ここで最初から Flutter や React Native や Swift を選ばない。三つの層を、下から順に登る。
| 層 | 道具 | 役目 |
|---|---|---|
| 第一層 | CLI ツール(Python) | 処理本体を書いて、動かして、確かめる |
| 第二層 | Flet アプリ(Python) | 画面が要るときに、Python のまま GUI を載せる |
| 第三層 | Flutter アプリ(Dart) | Flet の部品で足りないときだけ |
処理本体・確認"] Q1{"画面が要るか"} Done1(["uv tool install で配る"]) L2["第二層: Flet アプリ(Python)
Mac / Win / Linux / Web / iOS / Android"] Q2{"Flet で足りるか"} Done2(["各 OS の実行ファイルか
ストアで配る"]) L3["第三層: Flutter アプリ(Dart)
Flet の部品で足りないとき"] Start --> L1 --> Q1 Q1 -->|不要| Done1 Q1 -->|必要| L2 --> Q2 Q2 -->|足りる| Done2 Q2 -->|足りない| L3 classDef good fill:#e8f5e9,stroke:#7a9a6d,color:#3a4d34 classDef bad fill:#fef3e7,stroke:#c89559,color:#5a3f1a class L1,L2 good class L3 bad
アプリの本体は、入力を取って、処理して、出力することだ。だから最初に書くのはコマンドラインツールになる。テストしやすく、直しやすく、AI が書きやすい。動くようになったら、それで配れる ── uv tool install <ツール名> で、Python が入っているすべての OS に届く。データを処理する、ファイルを変換する、API を叩く。この種の道具は、第一層で完結する。
第二層に上がるのは、操作する人が技術者ではないとき、視覚的な手応えが要るとき、入力欄が複数あるときだ。
Flet を選ぶ理由は、同じ Python が全部の画面で動くことだ
Flet は、Python で書く GUI フレームワークだ。内側で Flutter のレンダリングエンジンを使うが、書くのは Python だけになる。第一層で書いた CLI の処理を、ほぼそのまま画面に載せられる。
import flet as ft
@ft.component
def Greeting():
name, set_name = ft.use_state("")
return ft.Column([
ft.TextField(label="名前", on_change=lambda e: set_name(e.control.value)),
ft.Text(f"こんにちは、{name}さん" if name else ""),
])
ft.run(lambda page: page.render(Greeting))
テキスト欄と表示領域のある GUI が、これで動く。*同じコードが、Mac でも Windows でも Linux でも、Web ブラウザでも、iOS / Android でも動く*。この連載で作る道具の画面は、 Flet を既定にする。
道具立ての軽さも効く。Flutter の開発環境(Android Studio・SDK・Xcode)が要らず、 Flet は Python の環境だけで足りる(Flutter の側は、配る形に組むときだけ展開される)。 CLI で動く処理に Flet の画面を足す追加の手間は、ライブラリの導入と数十行のコードだ。
現場で動く道具の形
第一層・第二層で完結する道具を、いくつか挙げる。
CLI で足りるもの
invoice── 月末の請求書一括生成。顧客マスタ(SQLite、2-03)+ 様式 → pandoc で PDF を百通minutes── 議事録の整形。録音.m4aを Whisper でテキスト化 → AI が Markdown に整え、要点を抜くfieldlog── 農作業の日報。写真と一言メモを受け取り日記にし、SQLite に貯めて月別の作業時間を集計する
Flet で画面を被せるもの
- 介護記録の入力 ── 介護士のタブレットで動く。入居者を選んで一言入力、写真を撮る → 手元の SQLite に保存 → 夜間に自分のサーバへ同期(2-02)
- 畑の管理マップ ── 地図の上で区画をタップし、その区画の作付け履歴を見て入力する
- 小売店の棚卸し ── 商品の QR を撮って数量を入れる → SQLite で集計 →
.xlsxで出す(2-07)
Flet は、Mac・Windows・Linux の実行ファイルも、App Store と Play Store に出す形も作れる(flet build)。第三層の Flutter に上がるのは、Flet の部品で足りない画面が要るときだけだ。社内や自分のための道具なら、第一層か第二層で足りる。
どれも、この章の Python と 2-03 の SQLite をそのまま使う。新しい枠組みを覚え直す必要は無い。
flet-mcp が、いまの版の書き方を渡す
Flet には MCP サーバ(flet-mcp)がある。AI の MCP 設定にこれを足すと、AI は
手元に入っている版 のドキュメントをその場で引ける。
これが効くのは、GUI のフレームワークが最も版で変わる場所だからだ。学習データの中にある古い書き方をそのまま出してしまうと、動かないコードから始めることになる。flet-mcp があると、AI は書く前にいまの書き方を確かめる。古い書き方が出にくくなる。
やることは、MCP の設定に flet-mcp を足して、AI に「Flet の書き方は MCP で確かめてから書いて」と伝えることだけだ。この一手間が、Flet を連載の既定の画面にできる理由でもある。
確かめ方
この章は、次の五つができていれば済みだ。
- ブラウザで JupyterLab が開き、セルに
import polarsと書いて Shift+Enter が通る - 手元の
.xlsxを Polars が読み、商品別・月別のクロス集計が画面に表で出る - 同じノートブックで Altair の図が描かれ、マウスを乗せると値が出る
- 基幹から出したデータだけで月次の帳票が作れて、基幹に触らずに何度でも作り直せる
- Flet のアプリが手元の画面で立ち上がり、同じコードが Web ブラウザでも開く
uv run jupyter lab
uv run python -c "import polars, altair, flet; print('ok')"
人が持つ物
人が渡す値
- 集計の対象にするファイルと期間、部門や商品の区分
- 人が決める区切りの値(例 大口 10 万円 / 中口 5 万円)
- 基幹から取り出してよいデータの範囲と、取り出す間隔
- 請求書の様式、送り先、締め日
- Flet アプリを配る相手と、動かす機械(タブレット、PC、Web)
AI が「やる前に言う」操作
- 人が作った
.xlsxに上書きする - 基幹システムへ書き込む(読み出しだけのはずの処理で)
- 請求書や通知メールを実際に送る
- VBA が入った元のファイルを差し替える、または消す
確かめた版と日付
- JupyterLab、uv、Miniforge、Polars、matplotlib、Altair ── 版は指定していない
- Flet ── 版は指定していない。書き方は
flet-mcpに、入っている版を確かめさせる - 手順を書いたのは 2026-09-21、見直したのは 2026-10-05
- 版が上がっていたら、AI に公式の手順を確かめさせてから進める
まとめ
処理を、Excel の中から Python の側へ。
- 使う能力 ── 文法を覚える代わりに、何を処理したいかを言葉にする。エラー文は次の指示の入力になる
- 外部化 ── マクロ・VBA・グラフ・ピボットを Python に出す。Excel は人の入出力として残り、
.xlsxのまま扱う - JupyterLab + Polars ── ピボットと VLOOKUP がコードになり、翌月は再実行だけで済む
- matplotlib / Altair ── 図がコードとして残り、Git に入り、毎月そのまま再生成される
- OLTP と OLAP の分離 ── 帳票・ダッシュボード・請求書を基幹から剥がす。月末の帳票実行で営業システムが固まる事故が消える
- CLI → Flet ── 処理を書いてから画面を被せる。同じ Python が Mac・Windows・Linux・Web・モバイルで動き、
flet-mcpが入っている版の書き方を渡す
ここで身につけた Python は、この先の章でそのまま使う。次章では、その道具とアプリの前に門番を置く。PocketBase で認証を一つにまとめ、どのアプリも同じ入口を通るようにする。