# Code.gs 修正レポート (2025-12-26) ## 🐛 問題点 ### 1. 予実シートを更新 - データが消える **原因**: `updateOutputSheet()` 関数が値を直接設定していた - VLOOKUPを使うべきところを、parseActualData()で値を取得して設定 - 実績データのマッピングが複雑で、エラーが発生しやすい ### 2. 経営ダッシュボードを更新 - エラー発生 **原因**: updateBudgetVsActual()が存在しない関数を呼び出していた - parseActualData()が正しく動作しない - データ構造の不一致 ## ✅ 修正内容 ### Code-v2.gs の主な変更点 #### 1. updateOutputSheetWithFormulas() - 完全書き換え **以前**: ```javascript // 値を直接設定 const budget = budgetData[index][mIndex] || 0; const actual = actualData[item.name][mIndex] || 0; sheet.getRange(row, col).setValue(budget); sheet.getRange(row, col + 1).setValue(actual); ``` **修正後**: ```javascript // VLOOKUP数式を設定 const budgetFormula = `=IFERROR(VLOOKUP($B${row},'予算入力'!$B:$O,${mIndex + 2},FALSE),0)`; const actualFormula = `=IFERROR(VLOOKUP($B${row},'実績入力'!$B:$T,${mIndex + 7},FALSE),0)`; sheet.getRange(row, col).setFormula(budgetFormula); sheet.getRange(row, col + 1).setFormula(actualFormula); ``` #### 2. 不要な関数を削除 削除した関数: - `parseActualData()` - VLOOKUPで代替 - `findItemName()` - VLOOKUPで不要 - `updateOutputSheet()` - updateOutputSheetWithFormulas()に統合 #### 3. PL_ITEMS の簡素化 **以前**: ```javascript const PL_ITEMS = [ { level: 0, name: '売上高' }, { level: 1, name: '売上高' }, // 重複 { level: 0, name: '売上高 計' }, // 不要 ... ]; ``` **修正後**: ```javascript const PL_ITEMS = [ { name: '売上高', level: 0 }, { name: '売上原価', level: 0 }, { name: '売上総損益金額', level: 0 }, ... // 重複なし、シンプル ]; ``` #### 4. 条件付き書式の追加 ```javascript function applyConditionalFormattingToOutput(sheet) { // 差異列: 正の値=緑、負の値=赤 const greenRule = SpreadsheetApp.newConditionalFormatRule() .whenNumberGreaterThan(0) .setFontColor('#38761d') .setRanges([range]) .build(); const redRule = SpreadsheetApp.newConditionalFormatRule() .whenNumberLessThan(0) .setFontColor('#cc0000') .setRanges([range]) .build(); } ``` #### 5. updateAll() 関数の修正 ```javascript function updateAll() { try { // 1. 予実シートを更新(VLOOKUP使用) updateOutputSheetWithFormulas(outputSheet); // 2. 経営ダッシュボードを更新 if (dashboard) { updateDashboardInternal(dashboard); } } catch (error) { ui.alert('エラー', error.message, ui.ButtonSet.OK); } } ``` ## 📋 VLOOKUP数式の仕組み ### 予算データ **予算入力シートの構造**: ``` B列: 項目名 C列: 2025-04 (VLOOKUP列番号=2) D列: 2025-05 (VLOOKUP列番号=3) ... N列: 2026-03 (VLOOKUP列番号=13) O列: 期間累計 ``` **数式**: ```javascript =IFERROR(VLOOKUP($B6,'予算入力'!$B:$O,2,FALSE),0) // $B6 = 項目名で検索 // '予算入力'!$B:$O = 検索範囲 // 2 = C列を返す (2025-04) // FALSE = 完全一致 ``` ### 実績データ **実績入力シートの構造**: ``` B列: 項目名 C-F列: 空/ラベル G列: 2025-04 (VLOOKUP列番号=7) H列: 2025-05 (VLOOKUP列番号=8) ... R列: 2026-03 (VLOOKUP列番号=18) S列: 期間累計 ``` **数式**: ```javascript =IFERROR(VLOOKUP($B6,'実績入力'!$B:$T,7,FALSE),0) // $B6 = 項目名で検索 // '実績入力'!$B:$T = 検索範囲 // 7 = G列を返す (2025-04) ``` ## 🎯 修正後の動作 ### 予実シート更新 1. シートをクリア 2. ヘッダーを作成(4行目: 月ヘッダー、5行目: サブヘッダー) 3. 各項目行にVLOOKUP数式を設定 - 予算: 予算入力シートから取得 - 実績: 実績入力シートから取得 - 差異: 実績 - 予算 - 達成率: 実績 / 予算 4. 条件付き書式を適用 - 差異: 正=緑、負=赤 - 達成率: 100%以上=緑、80%未満=赤 5. 列幅調整 ### 経営ダッシュボード更新 1. 期首月と締月を読み取り 2. 月数を計算 3. 各セクションを更新 - セクション1: 年間予算 vs 締月地点実績 - セクション2: 締月地点予算 vs 実績 - セクション3-6: 各種指標 4. すべて数式で自動計算 ## 📂 ファイル - `Code.gs` - 修正版(Code-v2.gsをコピー) - `Code.gs.old` - 以前のバージョン(バックアップ) - `Code-v2.gs` - 修正版(オリジナル) - `Code.gs.backup-YYYYMMDD-HHMMSS` - タイムスタンプ付きバックアップ ## 🚀 デプロイ方法 1. Google Sheetsを開く 2. 「拡張機能」→「Apps Script」 3. `Code.gs` の内容を全て削除 4. `20251226-update-google-sheet/Code.gs` の内容をコピー&ペースト 5. 保存 (Ctrl+S) 6. `onOpen` 関数を実行 7. 権限承認 8. スプレッドシートを再読み込み 9. メニューから「🔄 全て更新」を実行 ## ⚠️ 重要な注意事項 1. **シート名は変更しないでください**: - 予算入力 - 実績入力 - 予実出力 - 経営ダッシュボード 2. **シート構造を維持してください**: - 予算入力: B列=項目名、C~N列=月別データ - 実績入力: B列=項目名、G~R列=月別データ 3. **項目名は完全一致が必要**: - VLOOKUPは項目名で検索するため - スペースや全角/半角に注意 4. **初期化機能の使用**: - 問題が発生した場合は「初期設定」メニューから各シートを再初期化 ## ✅ テスト項目 - [ ] 予実シートを更新が正常に動作 - [ ] VLOOKUPで予算データが正しく表示 - [ ] VLOOKUPで実績データが正しく表示 - [ ] 差異が正しく計算される - [ ] 達成率が正しく計算される - [ ] 条件付き書式が適用される(緑/赤) - [ ] 経営ダッシュボードを更新が正常に動作 - [ ] 全て更新が正常に動作 --- **修正日**: 2025-12-26 **作成者**: Claude Code **バージョン**: 2.0