Excel解析から始める不動産投資収益シミュレーションWebアプリの設計と実装
長年育ててきた不動産投資収益シミュレーションのExcel(1法人2物件・35年分)を、Webアプリに作り替える作業を始めた。朝6時のセッションでExcel解析と設計、7時台からの新セッションで実装。1日で計算エンジンからExcel風のシート表示までたどり着いた。
まずExcelを解剖してもらう
最初の指示は「このExcelを解析して、シート間の数字のつながり・参照の構造・計算の流れ・最終的な目的をまとめてほしい」だった。あわせて、データはSingle Source of Truth(SSOT)を徹底した設計まで踏み込むことを条件にした。
Claude CodeはPythonでブックを開き、サブエージェント6体を並列に走らせてシートを手分けして解析した。返ってきたサマリーを読んで、シートのどこに入力があり、どこが計算結果で、どの数字がどのシートを参照しているかの全体像がつかめた。
ここで方向性を一言で固定した。
これは別ブックやアプリ化を見据えた論理設計方向で間違いないです。設計をゼロから引き直すイメージです。
Excelの構造をそのまま写すのではなく、①現状解析(as-is)と②SSOT論理設計(to-be)の2本のドキュメントに分けてまとめさせた。ドキュメントはCodexにレビューさせ、指摘の反映と再レビュー(resume --last で文脈維持)を経て承認まで通した。
Excelではモジュール化できない、をコードで解く
解析結果を眺めながら、自分の理解を確かめる質問を投げた。
Excelだとモジュール化するのってシート構造上結構難しいじゃないですか。これ今回それを拡張可能なように、つまりコードで拡張可能なようにオブジェクト化、あるいは抽象化してる設計ってことで合ってますか?
答えはYes。今回の設計は「シートではなく、データと関数を一級の構成単位にする」抽象化だった。Excelでは物件を1つ増やすとシートの複製とセル参照の張り直しが発生するが、コードなら物件オブジェクトを配列に1つ足すだけで済む。シートはあくまで「計算結果のビュー」であって、真実のデータ(入力前提)は1か所に置く。SSOTの徹底とはそういう意味になる。
実装計画とセッション跨ぎ
設計の次は実装計画。「UXが最高なものになるように。参考になるOSS実装があれば探して、ベストプラクティスを取り込んで構わない」と注文を付けた。OSS実装とUXパターンの調査を並列で走らせ、その結果を踏まえた計画書を memo/2026-06-12/ に書かせて、これもCodexレビューを通した。
未決事項は2点だけ自分で決めた。
- 物件名はいったん今のまま(後で変えるのは簡単)
- アプリ表示は年次のみ。月次資金繰り表はExcel側の役割として残す切り分け
ここでセッションを切り替えるため、復帰プロンプトを出させた。解析→設計→計画→未決事項の決定までを1セッション、実装を次のセッションに分ける運用にした。
Phase 0: 計算エンジンとExcel数値一致の回帰テスト
新セッションでは計画書と設計ドキュメントを読み込ませて、UIなしの計算エンジンから着手。型定義→借入返済→減価償却→法人税→FS組み立て→売却分析→連結→KPIの順に積み上げていく。
検証の柱は「現行Excelとの数値一致」に置いた。Excelの計算結果をfixtureとして取り出し、エンジンの出力と突き合わせる回帰テストを書かせた。
// Excelの35年分の計算結果をfixtureに固定し、エンジン出力と突き合わせる
expect(engineResult.corporateTax[year]).toBe(excelFixture.corporateTax[year])
ここで面白いズレが出た。物件02の税額が全年ちょうど70,000円だけ食い違う。調べると均等割の扱いがExcel側でシートによって違っており、Excelの癖(quirk)としてテスト側に明示して吸収した。Excelを正とした移植では、こういう「仕様なのかバグなのか」の判定が一番神経を使う。
赤字年度・売却年度・均等割のみの境界テストと不変条件テストまで足して、44テスト全パス。型チェック・lintもクリーンで、Phase 0完了とした。
Phase 1: ページと、Excel風シート表示
「ページを用意してくれてますか?」と聞いたら、Phase 0は計画どおりエンジンまでだった。この質問をGOサインとして、MVP UIの実装に進んでもらった。2ペインレイアウトで左に前提スライダー、右にKPIカードと手書きSVGチャート3枚。プリセット切替で即時再計算される。
動作確認ではプリセット切替でKPIが変わらないように見える場面があり、ブラウザで調査させたら、実はウィンドウ最大化でリサイズが効いていないだけだった。デバイスエミュレーションに切り替えてモバイル縦積みまで確認した。
仕上げにもう1つ注文した。
Excelのシートみたいに、返済計画表とか、シートに分かれててテーブルデータになってるやつ。あれを出してほしいんですけどね。
エンジンは全データを持っているので、ページ下部に「計算シート」セクションを追加。物件FS・法人FS・法人税・返済予定表(年次+月次360回)・減価償却・固都税・損益分岐点など10シートをExcel風タブで切り替えられ、先頭列固定の横スクロールテーブルで表示する。上の前提スライダーと連動して再計算されるので、Excelでセルを追いかけていた検算がブラウザ上で完結する。FSシートの数字がExcelと同じ値で並んでいるのを見て、画面を二度見した。
ステージングコミットと後始末
最後に「一旦ステージングコミットしといてください」で締め。docs・エンジン・UIの論理単位で3コミットに分けてもらった。途中、memoディレクトリが81MBに膨らんでいるのが見つかり、解析時に使ったExcel全シートダンプ(3.8MB)など使い終わったテキストデータを削除してからコミットした。
学び
- Excelの解析は「参照構造・計算の流れ・最終目的」の3点セットで頼むと、移植に必要な情報が一度で揃う
- SSOT設計は「シートをビューに格下げし、入力前提を1か所に集める」と言い換えると腹に落ちる
- Excel移植の回帰テストは数値一致が最強の安全網。ズレが出たらExcel側の癖を疑い、テストに明示して吸収する
- 解析・設計・計画と実装はセッションを分け、復帰プロンプトで引き継ぐと実装セッションが迷走しない
- 「画面の違和感を拾うのは自分、原因調査と修正はAI」の分業が今日も機能した