概要

項目内容
案件IDMAS-095
カテゴリデータマート
PhaseP2
優先度★★
所要時間15分
実装ステータス📝 仕様書段階・実装未着手 (2026-04-28 監査時点)
対象ファイル600_report/608_datamart_render.js

目的

72_bs_snap(B/Sスナップショット)のプルダウン選択肢とINDEX/MATCH数式を、isActualOnly=true 時に実績月のみに限定する。71_bs では既に isActualOnly パターンが実装済みだが、72_bs_snap のレンダラーが対応していない。

現在のステータス

コンポーネントisActualOnly対応
602_datamart_main.js(ctx設定 L234)ctx.isActualOnly = true
604_datamart_bs.js(B/S出力 L146-163)✅ filterBsValues + headerMonths分岐
608_datamart_render.js(スナップショット L44-74)❌ 未対応

現在のコード(608_datamart_render.js dmRenderBsSnapshot_)

プルダウン選択肢の構築(L71-72)

const snapChoices = ctx.targetMonthsWithActBgt.map(v => String(v).replace(/\n/g, ' '));
// → ["2025-08 (実績)", "2025-09 (実績)", ..., "2026-05 (予算)", ...]
// ★ isActualOnly でも予算月が選択肢に含まれる

INDEX/MATCH数式でのヘッダー参照(L64)

const matchExpr = `MATCH($B$1, ARRAYFORMULA(SUBSTITUTE('${bsSheetName}'!$B$2:$Z$2, CHAR(10), " ")), 0)`;
// → 71_bs のヘッダー行を参照。71_bs は isActualOnly=true で targetMonths(ラベルなし)を使用
// ★ 72_bs_snap のプルダウン値は "2025-08 (実績)" 形式だが、71_bs のヘッダーは "2025-08" 形式
// → SUBSTITUTE で改行をスペースに変換しても、"(実績)" ラベルの有無で不一致が発生する可能性

修正方針

dmRenderBsSnapshot_()ctx.isActualOnly を参照し、実績専用時はプルダウン選択肢を targetMonths(ラベルなし)に切り替える。

変更箇所

// L71付近: プルダウン選択肢の構築を分岐
var sourceMonths = ctx.isActualOnly ? ctx.targetMonths : ctx.targetMonthsWithActBgt;
const snapChoices = sourceMonths.map(v => String(v).replace(/\n/g, ' '));
// L54付近: 保存値の復元チェックも同様に分岐
const snapChoicesCheck = sourceMonths.map(v => String(v).replace(/\n/g, ' '));

境界月以降の除外

実績専用時は境界月以降の月をプルダウン選択肢から除外する。

var sourceMonths;
if (ctx.isActualOnly) {
  sourceMonths = ctx.targetMonths.filter(function(ym) {
    return ym < ctx.boundaryMonthStr;
  });
} else {
  sourceMonths = ctx.targetMonthsWithActBgt;
}
const snapChoices = sourceMonths.map(v => String(v).replace(/\n/g, ' '));

これにより:

  • 実績専用時: ["2025-08", "2025-09", ..., "2025-12"](実績確定月のみ)
  • 計画時: ["2025-08 (実績)", ..., "2026-07 (予算)"](全月)

影響範囲

  • 変更ファイル: 608_datamart_render.jsdmRenderBsSnapshot_() のみ
  • 変更量: sourceMonths 変数の追加(3-5行)+ 既存の ctx.targetMonthsWithActBgt 参照を sourceMonths に置換(2箇所)
  • 71_bs との整合性: 71_bs のヘッダーが targetMonths(ラベルなし)になるため、72_bs_snap のプルダウン値も同形式になり、INDEX/MATCH 数式の照合が正しく動作する

注意事項

  1. dmApplyDwhFormat_() は変更しない(72_bs_snap は dmRenderBsSnapshot_ で独自レンダリング)
  2. 保存されたプルダウン値(savedYm)の復元チェックでも sourceMonths を使うこと。旧形式の値("2025-08 (実績)")が保存されている場合、新形式("2025-08")と不一致になるため、復元に失敗してデフォルト値が設定される(問題なし)
  3. 計画タブ(73_bs_plan)はスナップショットを持たないため影響なし

関連ドキュメント

仕様書関連箇所
CLAUDE.md変更時の動作確認テスト: 600_report/6*_datamart_*.jsマート更新テスト
D.7 MAS-093 CFタブ実績専用モード同パターンの先行案件

人間が検討すべき事項

  • スナップショットの用途(月次報告 or 期末確定): 実績専用化により、確定月のみ選択可能になる。月次報告用途に適合

実装プロンプト(Claude Code 用)

あなたはGAS会計システム(bizlp-gas-accounting)のシニア開発者です。
案件 S-23「72_bs_snap の実績専用化」を実装してください。

## 実行前タスク

以下のファイルを読み込んでください:
1. `600_report/608_datamart_render.js` — `dmRenderBsSnapshot_()` の全体構造(L44-74)。プルダウン構築箇所(L54, L71-72)を確認
2. `600_report/604_datamart_bs.js` — `dmBuildBsOutput_()` での isActualOnly 実装パターン(L146-163)を参考に
3. `600_report/602_datamart_main.js` — L234の `ctx.isActualOnly = true` 設定、L299の dmRenderBsSnapshot_ 呼び出し
4. `docs/dev/dev_mas-095_bs_snap_actual_only.md`

## 修正対象ファイル

`600_report/608_datamart_render.js` の `dmRenderBsSnapshot_()` のみ。

## 実装内容

1. 関数冒頭で `ctx.isActualOnly` と `ctx.boundaryMonthStr` を読み取り
2. `sourceMonths` 変数を追加: isActualOnly なら `ctx.targetMonths` から境界月以降を除外、そうでなければ `ctx.targetMonthsWithActBgt`
3. L54付近の `snapChoicesCheck` と L71の `snapChoices` で `ctx.targetMonthsWithActBgt` → `sourceMonths` に置換

## 制約
- `dmApplyDwhFormat_()` は変更しない
- INDEX/MATCH数式のロジック(L64)は変更しない(プルダウン値の形式を71_bsヘッダーと一致させることで自動解決)

## 動作確認

`npm run push:dev` 後:
1. `buildBudgetTrendDataMart()` を実行
2. 72_bs_snap のプルダウンに実績確定月のみが表示されること(予算月が含まれないこと)
3. プルダウンで月を選択 → 金額が正しく表示されること
4. 再度マート更新を実行 → 選択した月が維持されること(sourceMonths に含まれる場合)

推奨実行モデル

工程推奨モデル理由
仕様書作成(本ドキュメント)Claude Opus 4.6INDEX/MATCH数式とプルダウン形式の整合性分析
実装Claude Haiku 4.5変数追加と2箇所の置換のみ。判断要素が少ない

変更履歴

日付変更内容
2026-04-14初版作成