• #eurekapu
  • #キャッシュフロー計算書
  • #リファクタリング
  • #Codex
  • #Excel
  • #JSON
  • #仕様設計
開発eurekapu-nuxt4アクティブ

この日やったこと

仮説検証用Excelの「サム単体」シートから勘定科目マトリックスを抽出し、論点×勘定科目の0/1マッピングをJSON化した。これを新しいマスタとして、既存の年次推移表生成スクリプトを丸ごと改修する仕様書を書き上げた。Codexレビューを3ラウンド回して致命的な指摘を潰し、実装まで踏み込んだ。夜の検証では33論点中8 OK / 25 NG / 2 SKIPというほろ苦い結果で区切り、翌朝6時のタスクとしてタスクサービスにNG論点の引き継ぎ計画を登録した。


なぜマトリックス化するのか

ハードコード地獄を終わらせる

既存の年次推移表生成スクリプトは、SUMIFSの数式内に勘定科目名を文字列リテラルで直書きしていた。

=IFERROR(INDEX(年次推移表!C$1:C$28,MATCH("貸倒損失",年次推移表!$A$1:$A$28,0)),0)

MATCH関数の第1引数が"貸倒損失"という文字列でハードコードされている。しかも同じExcel内のC列には科目名を整然と並べているにもかかわらず、その行を参照せずに文字列を直書きしていた。科目名が1文字でも揺れたら数式が壊れる。論点を跨いで科目が変わると、スクリプト側の生成ロジックを書き直す必要があった。

論点別フィルタリングを自動化する

キャッシュフロー計算書(CFWS)は、論点ごとに使う勘定科目が違う。Q9-3-2では長期貸付金と貸倒引当金が出るが、Q3-9では有形固定資産と減価償却累計額が主役になる。この「論点ごとに使う科目・使わない科目」を、スクリプトが自動で判定できる仕組みが必要だった。

そこで仮説検証用Excel(サム単体シート)から、横軸に論点番号(Q9-3-2、Q9-3-3 ...)、縦軸に勘定科目を並べ、使う=1 / 使わない=0のマトリックスを作ってJSONに落とした。スクリプトはJSONを引いて「この論点ではこの科目だけ出す」と判断できるようになる。

マトリックスから除外したもの

「現金及び預金合計」「営業CF」「現金及び預金_機種」など、合計行や集計ラベルはマトリックスに含めない。これらは計算結果として出てくるもので、マスタ側で0/1を切り替える対象ではないからだ。JSONとExcelマトリックスシートの両方から明示的に削った。


仕様書策定プロセス

問題発見から仕様書の骨子へ

最初のセッションで、既存スクリプトの年次推移表SUMIFS数式を眺めながら「MATCH関数の第1引数が全部ハードコードされている」と気付いた。ユーザーから「C列に全部名称を入れているのに、そこを参照せずに文字列を直書きしているのはおかしい」という指摘が入った瞬間、改修スコープが確定した。

仕様書の骨子は以下のとおり。

  1. 勘定科目マトリックスをJSON化(論点×科目の0/1テーブル)
  2. 年次推移表のSUMIFS数式をセル参照化(MATCH($A12, ...) のように同一シートのC列を引く)
  3. 期首残高・期末残高の計算も全てセル参照ベースに統一
  4. 論点ごとにマトリックスJSONを引き、必要な科目だけを年次推移表に出力
  5. CFWSの調整列との整合はcheck行で検証

Codex 3ラウンドレビュー

仕様書を書いたら、ExitPlanMode前にCodex(GPT-5.4)にレビューを投げる運用にしている。クソリプを除外する指示を入れて、致命的な点だけ返してもらう。

  • 1ラウンド目: Codexから3点の致命的指摘。MATCH関数の範囲指定が論点跨ぎで壊れる可能性、期首残高のSUMIFS混入リスク、マトリックスJSONのスキーマ定義不足
  • 2ラウンド目: スクリプト側の実装方針まで踏み込んで修正。さらに3点の致命的指摘。繰越利益剰余金の特殊処理、税引前当期純利益の独立セクション化、法人税等の扱い
  • 3ラウンド目: 全面書き直しに近い修正を投入してOKサインを受領

3ラウンドで致命的指摘が収束したので、ExitPlanModeして実装フェーズに入った。

税引前当期純利益と法人税等の独立セクション

Codex 2ラウンド目の指摘を受けて、年次推移表に「税引前当期純利益」と「法人税等」を独立したセクションとして追加する方針を入れた。法人税等(row 197)はマスタに1科目だけ存在し、Q3-4には含まれない。論点ごとに出し分ける設計にする。


実装と検証

Q3-4でまず完全一致を取る

Q3-4(棚卸資産の評価)の手修正版Excel(_KK.xlsx)を正解データとして、生成スクリプトの出力が完全一致するまで配賦ロジックを詰めた。check=0が両方(上半分・下半分)で取れて、繰越利益剰余金の5500 = 3400 + 2100も手計算と合った。

貸倒引当金の配賦ロジック(Q3-4の核心)

ユーザーから貸倒引当金の調整について鋭い指摘が入った。

「貸付金は売掛金と違い、関連する貸倒損失を個別に営業CFで調整する必要がある」という会計基準の原則に従い、以下の配賦ロジックを実装した。

K列(貸倒損失)= 長期貸付金 -1000 + 貸倒引当金_貸付債権 +700 + PL貸倒損失 +300 = 0

K列(調整列)の合計がゼロになることで、PL貸倒損失がCFに二重計上されない構造が完成した。Kの17セルで売上債権まで集計していた既存ロジックを切り離し、長期貸付金と貸倒引当金_貸付債権だけをK列で調整するように修正した。

全Q実行の結果: 8 OK / 25 NG / 2 SKIP

Q3-4で完全OKが取れたので、全33論点に展開した。結果は芳しくなかった。

  • OK: 8論点
  • NG: 25論点
  • SKIP: 2論点(Q5-22とQ3-8はソースxlsxに列がなく、マトリックスに含まれない)

filter補完ロジックを入れて再実行したが、数字は動かなかった。NG論点ごとに配賦ルールが微妙に違うようで、マトリックスだけでは判定しきれない領域が残っている。


引き継ぎ計画書の自動生成

Turso DBから書籍解説を引く

NG論点25件を翌日以降に引き継ぐため、各論点の解説を含む計画書を自動生成した。Turso DBのbook-knowledge-baseに書籍の解説テキストが入っているので、Q番号をキーに引いてくる。

最初の生成ではQ5-12等で別Qの解説が混ざる問題が発生した。Codexレビューで「Tursoのチャンク構造上、Q番号の境界で分割されていない箇所がある」と指摘されて、書籍タイトルをTursoから自動取得し、該当Qのチャンクのみから「Point」セクションを抽出するように修正した。

Codex 2ラウンドで計画書を仕上げる

1ラウンド目: 3点の致命的指摘(チャンク混ざり、書籍タイトルのハードコード、Point抽出ロジック)。全部潰して再生成した2ラウンド目でOKサイン。

タスクサービスに明日の朝6時タスクとして登録

add-taskスキルで、翌朝6時のタスクとして引き継ぎ計画書を登録した。朝Claude Codeを立ち上げたとき、すぐにNG論点の調査に入れる状態を作った。


学んだこと

  • ハードコード文字列は発見が遅れる。Excel生成スクリプトの場合、出力Excelを開いて数式バーを見ないと気付かない。JSONマスタとセル参照化はセットで入れるべき
  • Codexレビューは3ラウンドで収束することが多い。1ラウンド目で致命的指摘が3〜5個、2ラウンド目で2〜3個、3ラウンド目でOKというパターン
  • マトリックスJSONだけでは論点ごとの配賦ロジックの違いを吸収しきれない。配賦ルールのDSL化が次の課題になる
  • 正解データ(_KK.xlsx)を1件だけでも完全一致で取れると、他論点の検証コストが劇的に下がる。Q3-4を先に詰めた判断は正しかった

明日やること

  • NG 25論点のうち、貸倒引当金パターンで説明できる論点を洗い出す
  • 配賦ルールのDSL化を検討する(マトリックスJSONの拡張 or 別ファイル)
  • 繰越利益剰余金の特殊処理を他論点にも展開する
  • Turso DBの書籍解説チャンクの境界をQ番号単位で揃えるメンテナンスを入れる