背景と目的
長年使ってきた人生計画のExcelファイル(20シート構成)をWebアプリに移植するプロジェクトを開始した。Excelでは限界を感じていた点がいくつかある。
- シートが多すぎて全体像が把握しにくい
- 計算ロジックとデータが混在している
- 家族構成の変更(配偶者、子供の増減)に対応しづらい
- スマートフォンから確認できない
Webアプリ化することで、これらの課題を解決しつつ、より使いやすいUIを実現したい。
Excelファイルの分析
Claude Codeでxlsxスキルを使い、Excelファイルの構造を分析した。20シートの内訳は以下の通り。
入力系シート:
- 基本情報(生年月日、退職予定年齢など)
- 本人の収入
- 配偶者の収入
- 子供情報(3人分)
計算系シート:
- 社会保険料計算
- 所得税・住民税計算
- 年金受給額計算
出力系シート:
- 年次キャッシュフロー表
- 累計資産推移グラフ
- ライフイベント一覧
ミラーカラムUIの採用
UIとしてミラーカラムUIを採用することにした。
採用理由
- 全体像が常に見える: Excelではシートタブが隠れがちだが、ミラーカラムなら階層が一覧できる
- 入出力の分離: タブで「入力」と「出力」を分け、それぞれをミラーカラムで表現できる
- 数値の参照関係が追いやすい: どの入力がどの出力に影響するか、視覚的に理解しやすい
想定レイアウト
[タブ: 入力]
├─ 本人
│ ├─ 基本情報
│ ├─ 収入
│ └─ 社会保険
├─ 配偶者
│ └─ ...
└─ 子供1〜5
└─ ...
[タブ: 出力]
├─ 年次CF
├─ 資産推移
└─ 結論
冗長バッファ設計
ミラーカラムUIと相性が良い設計として「冗長バッファ」を採用した。
考え方
- 配偶者は「夫/妻」ではなく「配偶者」として汎用的に定義
- 子供は最初から5人分の枠を用意
- 使わない項目はゼロまたはdisplay: noneで非表示
メリット
- 動的追加が不要: フォーム項目を動的に追加する複雑なロジックが要らない
- 男女どちらでも対応: 「配偶者の収入」という汎用的な項目名なら性別を問わない
- ビューで邪魔にならない: ミラーカラムなら未使用項目は折りたためるので、Excelほど冗長さが目立たない
日本の家庭で子供が5人を超えるケースは稀なので、これで実用上は十分カバーできる。
フロントエンド先行開発
計算ロジックは後回しにして、まずフロントエンドから作る方針にした。
理由
- 見た目の最適化が先: ExcelのビューをそのままWebに移植すると冗長になる。必要な情報だけを見やすく配置したい
- 計算ロジックは変わらない: Excelの数式を移植すればいいので、後からでも対応できる
- 早期にフィードバックが得られる: 画面を見ながら「ここはもっとシンプルにしたい」という気づきが出てくる
進め方
- Excelの固定値をそのままハードコードして画面を作る
- 見た目を調整し、不要な項目を削る
- 計算ロジックを実装してハードコードを置き換える
- マスターデータ(税率テーブルなど)を外部化
技術スタック
Nuxt 4 + Scoped CSS
TailwindではなくScoped CSSを採用した。
Tailwindを避けた理由:
- クラス名が長くなりHTMLが読みづらい
- Claude Codeで編集する際、クラス名の組み合わせを覚えるコストがある
- 今回はコンポーネント単位でスタイルを閉じ込められればいい
Scoped CSSのメリット:
- コンポーネントファイル内で完結する
- CSSの記法がそのまま使える
- Claude Codeとの相性が良い(普通のCSSを書くだけ)
<style scoped>
.income-table {
width: 100%;
border-collapse: collapse;
}
.income-table th {
background: #f3f4f6;
padding: 8px;
}
</style>
データ保存
初期段階ではJSONまたはCSVで十分。将来的にはSQLiteも検討するが、性能が問題になるほどのデータ量ではない。
別プロジェクトとしての運用
このプロジェクトは既存のtax-assistantリポジトリとは別に作成することにした。
理由
- 関心事が異なる: tax-assistantは税務計算、こちらは人生設計
- 依存関係を減らせる: 独立したリポジトリならそれぞれ自由に変更できる
- 規模が大きくなりそう: 最初から分けておいた方が管理しやすい
@add-directoryによる参照
Claude Codeでは@add-directoryコマンドで別プロジェクトを参照できる。
@add-directory C:\Users\numbe\Git_repo\tax-assistant
これで両方のコードベースを見ながら作業できる。ただし、明示的に「tax-assistantのミラーカラムコンポーネントを参考にして」と指示する必要がある。自動では参照してくれない。
参照すべきコンポーネント
既存のtax-assistantで使っているミラーカラム関連のコンポーネントは以下の通り。
| ファイル | 説明 |
|---|---|
MillerColumnsView.vue | メインレイアウト |
MillerSidebar.vue | 左サイドバー |
MillerContent.vue | コンテンツエリア |
ただし、これらはtax-assistant固有のロジックと結合しているため、そのままコピーはできない。CSSのレイアウト部分を参考にして、新規に作成する必要がある。
ミラーカラムUIの本質
確認してわかったこと: ミラーカラムUIの核心はCSSにある。
.miller-layout {
display: flex;
height: 100vh;
}
.miller-column {
flex: 0 0 200px;
border-right: 1px solid #e5e7eb;
overflow-y: auto;
}
.miller-content {
flex: 1;
overflow-y: auto;
}
Vueの実装は階層データの管理とクリック時の選択状態更新がメインで、それほど複雑ではない。新規プロジェクトでは、この基本構造をベースに、人生計画に特化したUIを構築する。
今後の計画
- Phase 1: 結論画面とインプット画面のUIを作成
- Phase 2: Excelの固定値をハードコードして表示確認
- Phase 3: 計算ロジックの実装
- Phase 4: マスターデータの外部化
計算ロジックより先にUIを作り込むことで、本当に必要な機能だけに絞り込める。Excelをそのまま移植するのではなく、Webならではの使いやすさを追求したい。
関連リンク
- ミラーカラムUI - UIの採用理由と設計
- 不動産投資シミュレーションExcel移植計画 - 同様のアプローチで進めている別プロジェクト