3表から4表へ — S/Sを足したくなった
/lessons/financial-statements/cockpit-00-summary のコクピットページは、BS・PL・CSの3表を画面に並べて取引ごとに数字が動く構造で運用していた。配当や当期純利益振替の取引を進めると、BS の繰越利益剰余金が動く様子を見せたいが、3表の中だけでは「動いた」事実だけが見えて、その内訳を表現する場所がなかった。
利益剰余金の3行(繰越利益剰余金・当期純利益・利益準備金)をBSの中に並べていたが、横並びで縦に詰めても見づらかった。株主資本等変動計算書(S/S)を独立させて、純資産の動きはS/Sで表現する方針に切り替えた。
BS から利益剰余金の3行を削除して、CockpitSs.vue を新しいコンポーネントとして追加。BS の純資産は1行(純資産合計)に集約した。
SVGコネクターの矢印が邪魔だった
3表時代から、BSの現金とCSの期末現金残高をSVGコネクターで結んでいた。S/Sを追加した結果、BSの純資産合計とS/Sの純資産合計を結ぶ線も足したくなった。ここで2つ問題が出た。
矢印 → 塗りつぶし丸への変更
矢印のヘッドが太くて、線の終端で表全体の数字に被って読みづらかった。「BS の現金が CS の期末残高につながっている」という意味を表現したいだけで、方向性は不要だ。
矢印の代わりに**塗りつぶし丸(●)**を線の両端に置く形に変更した。「ここで接続している」という事実だけ示せれば足りる。
z-index 45 → 60
SVGコネクターをBS/CSの上に被せていたが、ホバー時のガイドハイライト(z-index 50台)に隠れる事象が発生した。コネクターが消えると接続が分からなくなる。
コネクター側のz-indexを45から60に上げて、ガイドハイライトより前面に出した。
left/leftバグ — elbow midX計算
これが一番ハマった。BS現金 → CS期末残高のelbowコネクター(L字に曲げる線)で、両端のアンカーが同じ「left」サイドに付いている時、midX(曲がり位置のX座標)が画面外に飛んでいた。
調べると、midX計算が「右 → 左」の前提で書いてあって、「左 → 左」の場合に符号が逆転していた。条件分岐を追加して、両端が同じサイドの場合は外側に膨らませるロジックに修正。
// 両端が左サイドの場合、midXは両アンカーの左外側に置く
const midX = isLeftLeft
? Math.min(startX, endX) - 24
: (startX + endX) / 2
BS↔S/S は純資産合計同士で結ぶ
最初は「当期純利益」のリンク先を S/S の繰越利益剰余金行にしていたが、SVGコネクターは別途「BS純資産合計 ↔ S/S純資産合計」を結ぶ形に整理した。ガイド(ハイライト)は当期純利益、コネクターは合計同士で役割を分けた。
VOICEVOX辞書 → 音声134ファイル再生成
SS関連の解説音声を生成したら、ずんだもんが「かぶぬししほんとうへんどうけいさんしょ」を読み間違えた。「株主資本等」を「かぶぬし・しほん・とう」と切らずに、別の読み方になっていた。
voicevox-dict-register スキルでユーザー辞書に登録。
- 単語:
株主資本等変動計算書 - 読み:
カブヌシシホントウヘンドウケイサンショ
辞書登録後、SS関連の音声16ファイルだけ再生成すれば足りると思っていた。しかし、Excel風貼り付けの解説文ガイドで「行」を含むステップ(解説文に「○行目」と出てくるもの)を確認したら、「行」の読みが「ぎょう/こう」で揺れていた箇所が他のステップにも残っていた。
結局、全134音声ファイルを再生成してR2に再アップロードした。再生成は1ファイルずつ走らせると時間がかかるので、バッチで流した。R2への再アップロードもまとめて実行。
BS左右の合計行が揃わなかった — grid再構成
BSの左右(資産 / 負債・純資産)で、合計行のY位置が微妙にズレていた。
最初に試したのは padding/margin の手調整。資産側に項目が多いか少ないかで合計行が上下するので、空行を挟んで揃える方式を試したが、取引によって項目数が変わると破綻する。
最終的に grid-template-areas を分割する方式に切り替えた。
- BS全体を「資産明細エリア / 負債純資産明細エリア / 合計行エリア」に分割
- 合計行エリアは左右ともに同じ grid 行に配置
- 明細エリアの高さが違っても、合計行は別エリアなのでY位置が完全に一致
検証で getBoundingClientRect() を使って top の差を測ったら、差が0pxになった。
レイアウト入れ替えとタイトル統一
S/Sを追加した結果、画面上の配置を見直した。BSとCSのレイアウトを入れ替え(grid-template-areas を再定義)、4表(BS / PL / CS / S/S)のタイトルを CS-method-label スタイルに統一した。
BSとPLとCSとS/Sで似たような色違いのラベルを使い回していたが、画面に4つ並ぶと色のバリエーションがうるさい。同じスタイルで統一して、表の中身(数字)に視線が集まるようにした。
バグ — 配当金行に幽霊の値が出た
S/Sの数値カウントアップアニメーションを AnimatedNumber で実装した後、画面チェックでバグが出た。
no-04時点(配当決議より前)で、SS表の配当金行に「35」が表示されている。配当はno-25付近で発生する取引なので、no-04では0でないとおかしい。
調べると、-0 が表示されるケースがあって、そこで JS が変な丸めをした結果が35になっていた。Math.abs() を通して -0 を 0 に正規化する処理を追加。
もう1件、no-17のstep 3でハイライトが PL を指していた。意図は「BSの短期借入金(shortLoanPayable)」だったのに、ガイドの参照先テーブルが PL になっていた。topicsデータの参照先を BS に修正。
取引アニメーションのトグル化
取引を進めるとBSやPLの数字がカウントアップする演出が走る。デバッグで「取引23(決算)」を何度も流し直すとアニメーション待ちが鬱陶しい。
任意トグルで切り替える形に変更。デフォルトは off。デバッグ時だけ on にする運用にした。
加えて、取引23(決算)のロジックを簡略化して、ボタン名を「決算を確定する」に変更。closing 処理時はアニメーションをスキップして即時実行に倒した。
localStorage永続化 — モーダル対策
取引を進めている途中で「決算」モーダルを開くと、画面遷移で currentEntryId が初期化されてしまうケースがあった。
localStorage に currentEntryId を保存する形に変更。ただし、entryRange (取引の範囲セット)ごとに別キーで保存する。同じURLでも entryRange が違えば別の進行状態として扱う。
const storageKey = `cockpit:currentEntryId:${entryRange}`
法人税等の説明文 — 厳密化
ガイドの説明文を見直していて、「税引前当期純利益 × 税率 = 法人税等」と書いていた箇所が目に止まった。これは厳密には間違いで、所得を確定(加算減算調整)した上で税率を乗算するのが正しい。
「税引前当期純利益にそのまま税率を乗じる」と読まれない表現に書き直した。簿記3級レベルでは加減算調整の話まで踏み込まないが、誤った認識を植えつけないように曖昧さを残す表現にした。
ハイライトを行→セルに
ガイドハイライトは元々「該当行全体」を黄色で囲んでいた。S/Sを追加して列が増えた結果、行全体ハイライトだと「どの数字を見るべきか」が分かりにくくなった。
特定セル(行×列の交点)だけをハイライトする形に変更。例えば「当期純利益が振り替わる」ステップでは、PLの当期純利益セルと S/S の当期純利益セルだけ光る。視線が迷わない。
公開化
最後に topics.ts から該当エントリの draft タグを外して公開化。SEO description に「株主資本等変動計算書(S/S)を追加した4表構成」の言及を足した。
3表で完結していたものを4表に増やすと、画面のスペース配分・コネクター・音声・ガイドの全部に手が及んで、想定の3倍くらい時間がかかった。終わってみると、利益剰余金の動きが S/S の中で完結して見える構造の方が、簿記の説明としても素直だ。先に4表で設計しておけばよかったとは思うが、3表で運用してから不足を感じて足す流れの方が、何が必要かは見えやすかった気もする。