我が家専用の家計調査票が完成する!自動生成テンプレート
簡単な「問診票(5ステップ・10個の質問)」に答えるだけで、
我が家に必要な家計項目が自動生成されるGoogleスプレッドシートテンプレートです。
病院で問診票を書くようにポチポチと環境(家族構成、住まい、車など)を選択するだけで、システムが裏側で「我が家専用の入力シート」を自動レイアウト。1円単位の細かい家計簿ではなく、年間ベースのお金の現在地(地図)をクリアに可視化します。
※ Googleアカウントでのログインが必要です
この自動生成ツールの特徴
- Googleスプレッドシートで作成(ご自身のドライブにコピーしてすぐ使えます)
- 問診票(5ステップ・10個の質問)形式(答えるだけでシステムが最適な項目枠を自動セットアップ)
- マージ(引き継ぎ)機能搭載(問診票を再生成しても、入力済みの単価やメモを崩さず維持)
- 「単価×回数/年」で計算(毎月と年数回の出費をすべて「年間金額」に統一して評価)
- 5つのハコで現在地を見える化(収入・固定費・変動費・貯蓄・資産を整理して自動集計)
- プログラミング知識不要(自動化のGASコードは組み込み済み。あなたはクリックするだけ)
こんなご家庭におすすめ
- 家計簿を始めたいが、どんな項目を立てればいいか分からなくて挫折した
- 共働き、子ども複数、車複数台などがあり、我が家にピッタリの項目を考えるのが面倒
- 毎月の生活費と、年1回(自動車税や更新料など)の特別支出が混ざって収支予測が破綻しがち
- レシートを1円単位で記録するより、年間の「現在地(いくら余るのか)」をざっくり把握したい
- 状況が変わってもゼロから作り直さず、長く使い続けられる家計シートがほしい
シート構成と使い方ガイド
このテンプレートは、ユーザーが必要な項目を自分で考えて並べる手間を省き、問診票に答えてボタンを押すだけで自動で専用の表を作成します。ホームページ上で使い方をスムーズに進められるよう、画像とともにステップを解説します。
シート構成(概要)
| シート名 | 役割・説明 |
|---|---|
| 問診票 | ご家族構成、お小遣い、サブスク、車、資産などの状況にポチポチ答える最初のハブシート。 |
| 入力シート | 問診票の回答結果を元に自動レイアウトされる、我が家専用の金額入力シート。 |
| 家計調査票(集計) | 入力データを元に自動で描画される「5つのハコ」で分類された年間収支・資産集計表。 |
| Settings | 非表示シート。マージや描画ロジックの動作設定(※通常は触る必要はありません)。 |
📝 スムーズに始めるための4ステップ
STEP 1:テンプレートをコピーして開く
ページ上下にあるダウンロードボタンからスプレッドシートを開き、メニューの「ファイル」 > 「コピーを作成」を選択してご自身の Google ドライブに保存します。コピーしたファイルは完全プライベートな状態になり、入力した金額が他人に送信されることは一切ありません。
STEP 2:問診票シートに答える(5つのステップ)
シート「問診票」を開き、あなたの家庭状況についてチェックを入れたり、数値を入力したりしていきます。
- STEP 1:ご家族と収入について(配偶者、子どもの人数、ボーナス、児童手当など)
- STEP 2:お小遣いと習い事について(お小遣い制人数、習い事の数)
- STEP 3:通信・サブスク・保険について(スマホ台数、回線有無、サブスク・保険契約数)
- STEP 4:住まいと車について(賃貸・持ち家の選択、車の保有台数など)
- STEP 5:その他と資産について(ローン、ペット、投資、普通預金口座の数)
STEP 3:メニューから「入力シート」を作成する
問診票をすべて答え終えたら、上部メニューの 「📝 家計調査票メニュー」 > 「1. 問診票から入力シートを作成」 をクリックします。これで、問診票のチェック状態に合わせた我が家専用の「入力シート」が一発で自動レイアウトされます。
このテンプレートでは、自動レイアウトと集計表自動描画のために Google Apps Script (GAS) というプログラムが動いています。初回のみ、Googleのセキュリティ制限により「実行の承認(許可)」画面が出ます。
驚かれるかもしれませんが、安全ですので以下の手順に沿って「許可」を完了させてください。
「承認が必要です」ダイアログで「権限を確認」を選択した後、警告画面(確認されていません)が出たら、左下にある「詳細」リンクをクリックして展開します。
詳細の中に表示される「(プロジェクト名)(安全ではないページ)に移動」をクリックします。
Googleアカウントへのアクセス権限リクエスト画面が表示されるので、スクロールして右下の「許可」(または「続行」)をクリックします。これでプログラムが動くようになります。
💡 スクショ付きでもっと丁寧に認証手順を確認したい方はこちら:
👉 GASの認証(許可)のやり方を画像つきで見る
「チェックし忘れた項目があった」「後から状況が変わった」という場合でも、問診票シートに戻ってチェックを直し、再度「1. 問診票から入力シートを作成」をクリックすれば何度でも作り直せます。
このとき、システムは入力シートのA〜D列(対象者・大項目・カテゴリ・項目名)を基準にして、すでに入力されたデータがあるかを判断しています。そのため、自動生成されたA〜D列のセルをご自身で書き換えていなければ、入力済みの「単価」「回数」「メモ」が消えてしまうことはありません。
STEP 4:単価・回数を入力し、集計表を最新化する
作成された「入力シート」に、それぞれの単価(金額)と「回数/年」を入力します。
本シートの最大の特徴は、あらゆる出費を「年間金額に統一して評価する」点です。毎月のもの、年数回のものを回数指定するだけで自動で年間換算してくれます。
| 項目の例 | 単価(1回分の金額) | 回数/年 | 年間金額(自動計算) |
|---|---|---|---|
| 毎月の食費 | 60,000 円 | 12 | 720,000 円 |
| 夏・冬のボーナス | 400,000 円 | 2 | 800,000 円 |
| 水道代(2ヶ月に1回) | 8,000 円 | 6 | 48,000 円 |
| 自動車税(年1回) | 35,000 円 | 1 | 35,000 円 |
| 賃貸の更新料(2年に1回) | 100,000 円 | 0.5 | 50,000 円 |
金額の入力が完了したら、再びメニューから 「📝 家計調査票メニュー」 > 「2. 集計表を最新化する」 をクリックします。
すると、「家計調査票(集計)」シートが自動でクリア&再描画され、「年間支出合計」や「年間収支予測」「5つのハコ(収入・固定費・変動費・貯蓄・資産)」で整理された現在地マップが浮かび上がります。
⚠️ ご利用時の注意事項
近年スプレッドシートに追加された「表に変換する」機能を使用すると、列のデータ型(数値・テキスト)が強制固定され、メニューから集計表を作成する際に 「型付きの列でセルの数値形式を設定することはできません」 というエラーが発生する原因になります。セルの書式は標準状態のままご使用ください。
ダウンロード(コピー)はこちら
テンプレートをコピーして使う(無料)※ Googleアカウントでのログインが必要です
補足・注意事項
- 本テンプレートは Google スプレッドシート形式です
- コピー後はご自身に合わせて自由に編集・カスタマイズできます
- 商用利用目的での複製や再配布はご遠慮ください
もっと詳しく知りたい方へ
本ツールの開発秘話や家計管理の考え方については、noteでも詳しく発信しています。
noteで解説を読む🛠(おまけ)中で動いているGASプログラム
「裏側でどのような処理が動いているのか知りたい」「自分でさらに追加カスタマイズしてみたい」という開発者向けに、シートに組み込まれている Google Apps Script の全コードを公開しています。通常の使用では読む必要はありません。
組み込まれているGASコードを展開して見る
/**
* 見える化家計調査票 セットアップスクリプト
*
* 1. 問診票シートから「入力シート」を自動生成する
* 2. 入力シートから「集計表シート(ダッシュボード)」を自動生成する
*/
function onOpen() {
const ui = SpreadsheetApp.getUi();
ui.createMenu('📝 家計調査票メニュー')
.addItem('1. 問診票から入力シートを作成', 'generateInputSheetFromIntake')
.addItem('2. 集計表を最新化する', 'generateSummarySheet')
.addToUi();
}
/**
* 問診票シートのチェックボックスを読み取り、入力シートを動的に生成する
*/
function generateInputSheetFromIntake(isFromMenu = true) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const intakeSheet = ss.getSheetByName('問診票');
if (!intakeSheet) {
if (isFromMenu) SpreadsheetApp.getUi().alert('エラー', '「問診票」シートが見つかりません。シート名を確認してください。', SpreadsheetApp.getUi().ButtonSet.OK);
return;
}
let inputSheet = ss.getSheetByName('入力シート');
const existingDataMap = new Map();
let isUpdate = false;
if (inputSheet) {
if (isFromMenu) {
const response = SpreadsheetApp.getUi().alert("確認", "既存の「入力シート」の入力内容(金額や回数)を引き継いだまま、問診票のチェック状態を反映して項目を更新しますか?", SpreadsheetApp.getUi().ButtonSet.YES_NO);
if (response !== SpreadsheetApp.getUi().Button.YES) return;
}
isUpdate = true;
// 既存データを退避
const existingValues = inputSheet.getDataRange().getValues();
if (existingValues.length > 1) {
for (let i = 1; i < existingValues.length; i++) {
const row = existingValues[i];
const target = row[0];
const mainCat = row[1];
const subCat = row[2];
const itemName = row[3];
const userMemo = row[4];
const price = row[5];
const times = row[6];
// ユニークキーは対象者、大項目、カテゴリ、自動生成項目名で固定(ユーザーが書き換えないD列までの情報)
const key = `${target}_${mainCat}_${subCat}_${itemName}`;
existingDataMap.set(key, { userMemo: userMemo, price: price, times: times });
}
}
inputSheet.clear();
} else {
inputSheet = ss.insertSheet('入力シート');
}
// デフォルト項目(全家庭共通): [対象者, 大項目, カテゴリ, 項目名(自動生成), メモ(自由記入), 単価, 回数/年]
let dataRows = [
["世帯主", "収入", "給与", "毎月の手取り", "", "", 12],
["共通", "固定費", "光熱費", "電気代(平均)", "", "", 12],
["共通", "固定費", "光熱費", "ガス代(平均)", "", "", 12],
["共通", "固定費", "光熱費", "水道代(平均)", "", "", 6],
["共通", "変動費", "食費", "スーパー等", "", "", 12],
["共通", "変動費", "外食", "外食・テイクアウト", "", "", 12],
["共通", "変動費", "日用品", "ドラッグストア等", "", "", 12],
["共通", "変動費", "美容衣服", "美容院・服代", "", "", 12],
["共通", "資産", "銀行", "普通預金残高", "", "", 1]
];
// 問診票の読み取り (C列:チェックボックス, D列:数値)
const isChecked = (row) => intakeSheet.getRange(`C${row}`).getValue() === true;
const getNum = (row) => parseInt(intakeSheet.getRange(`D${row}`).getValue()) || 1;
// STEP 1
if (isChecked(5)) {
let num = getNum(5);
for (let i = 1; i <= num; i++) {
dataRows.push(["共通", "固定費", "教育費", `学校・保育料等(子ども${i})`, "", "", 12]);
dataRows.push(["共通", "変動費", "子ども費", `生活・洋服代等(子ども${i})`, "", "", 12]);
}
}
if (isChecked(7)) dataRows.push(["世帯主", "収入", "賞与", "ボーナス", "", "", 2]);
if (isChecked(8)) dataRows.push(["配偶者", "収入", "給与", "毎月の手取り", "", "", 12]);
if (isChecked(9)) dataRows.push(["配偶者", "収入", "賞与", "ボーナス", "", "", 2]);
if (isChecked(10)) {
let num = getNum(10);
for (let i = 1; i <= num; i++) {
dataRows.push(["家族", "収入", "児童手当", `児童手当(子ども${i})`, "", "", 12]);
}
}
// STEP 2
if (isChecked(13)) {
let num = getNum(13);
for (let i = 1; i <= num; i++) dataRows.push(["共通", "変動費", "お小遣い", `お小遣い(${i}人目)`, "", "", 12]);
}
if (isChecked(15)) {
let num = getNum(15);
for (let i = 1; i <= num; i++) dataRows.push(["共通", "固定費", "習い事", `習い事・塾(${i}つ目)`, "", "", 12]);
}
// STEP 3
if (isChecked(18)) {
let num = getNum(18);
for (let i = 1; i <= num; i++) dataRows.push(["共通", "固定費", "通信費", `スマホ代(${i}台目)`, "", "", 12]);
}
if (isChecked(19)) dataRows.push(["共通", "固定費", "通信費", "自宅ネット回線", "", "", 12]);
if (isChecked(21)) {
let num = getNum(21);
for (let i = 1; i <= num; i++) dataRows.push(["共通", "固定費", "サブスク", `サブスク(${i}つ目)`, "", "", 12]);
}
if (isChecked(23)) {
let num = getNum(23);
for (let i = 1; i <= num; i++) dataRows.push(["共通", "固定費", "保険料", `保険料(${i}つ目)`, "", "", 12]);
}
// STEP 4
if (isChecked(26)) {
dataRows.push(["共通", "固定費", "住宅費用", "家賃・管理費", "", "", 12]);
dataRows.push(["共通", "固定費", "住宅費用", "賃貸の更新料", "", "", 0.5]);
}
if (isChecked(27)) {
dataRows.push(["共通", "固定費", "住宅費用", "住宅ローン月額", "", "", 12]);
dataRows.push(["共通", "固定費", "住宅費用", "固定資産税", "", "", 1]);
dataRows.push(["共通", "固定費", "住宅費用", "修繕積立金・その他", "", "", 12]);
}
if (isChecked(29)) {
let num = getNum(29);
for (let i = 1; i <= num; i++) {
dataRows.push(["共通", "変動費", "車", `ガソリン代・ETC(${i}台目)`, "", "", 12]);
dataRows.push(["共通", "固定費", "車", `自動車税(${i}台目)`, "", "", 1]);
dataRows.push(["共通", "変動費", "車", `車検・メンテ代(${i}台目)`, "", "", 1]);
dataRows.push(["共通", "固定費", "車", `自動車保険(${i}台目)`, "", "", 12]);
}
}
if (isChecked(30)) dataRows.push(["共通", "固定費", "住宅費用", "駐車場代", "", "", 12]);
// STEP 5
if (isChecked(33)) dataRows.push(["共通", "固定費", "ローン", "奨学金・各種ローン返済", "", "", 12]);
if (isChecked(34)) dataRows.push(["共通", "変動費", "ペット", "ペットのエサ代・病院代など", "", "", 12]);
if (isChecked(35)) {
let num = getNum(35);
for (let i = 1; i <= num; i++) {
dataRows.push(["共通", "貯蓄", "投資・運用", `積立・投資(${i}つ目)`, "", "", 12]);
}
}
if (isChecked(36)) {
let num = getNum(36);
for (let i = 1; i <= num; i++) {
dataRows.push(["共通", "資産", "預金・投資", `資産残高(${i}つ目)`, "", "", 1]);
}
}
// 収入を上部に固め、さらに対象者でソートする
const orderMain = { "収入": 1, "固定費": 2, "変動費": 3, "貯蓄": 4, "資産": 5 };
const orderTarget = { "世帯主": 1, "配偶者": 2, "家族": 3, "共通": 4 };
dataRows.sort((a, b) => {
if (orderMain[a[1]] !== orderMain[b[1]]) {
return (orderMain[a[1]] || 99) - (orderMain[b[1]] || 99);
}
// 同じ大項目の場合は、対象者でソート
return (orderTarget[a[0]] || 99) - (orderTarget[b[0]] || 99);
});
// 既存データが存在すればマージする
if (isUpdate && existingDataMap.size > 0) {
for (let i = 0; i < dataRows.length; i++) {
const row = dataRows[i];
const key = `${row[0]}_${row[1]}_${row[2]}_${row[3]}`;
if (existingDataMap.has(key)) {
const saved = existingDataMap.get(key);
row[4] = saved.userMemo; // メモを引き継ぐ
row[5] = saved.price; // 単価を引き継ぐ
row[6] = saved.times; // 回数を引き継ぐ
}
}
}
// ヘッダー書き込み
const headers = ["対象者", "大項目", "カテゴリ", "項目名(自動生成)", "メモ(自由記入)", "単価", "回数/年(※実態に合わせて変更)", "年間金額"];
inputSheet.getRange(1, 1, 1, headers.length).setValues([headers]);
inputSheet.getRange(1, 1, 1, headers.length).setBackground("#4a86e8").setFontColor("white").setFontWeight("bold");
// データ書き込み
if (dataRows.length > 0) {
inputSheet.getRange(2, 1, dataRows.length, 7).setValues(dataRows);
}
// 年間金額(H列)に数式を設定(=F2*G2)
const lastRow = Math.max(2, dataRows.length + 1);
const formulaRange = inputSheet.getRange(2, 8, lastRow - 1, 1);
formulaRange.setFormulaR1C1("=IF(ISBLANK(R[0]C[-2]), 0, R[0]C[-2] * R[0]C[-1])");
// 見た目の調整
inputSheet.setColumnWidth(1, 100); // 対象者
inputSheet.setColumnWidth(2, 100); // 大項目
inputSheet.setColumnWidth(3, 130); // カテゴリ
inputSheet.setColumnWidth(4, 200); // 項目名(自動生成)
inputSheet.setColumnWidth(5, 150); // メモ(自由記入)
inputSheet.setColumnWidth(6, 100); // 単価
inputSheet.setColumnWidth(7, 220); // 回数/年
inputSheet.setColumnWidth(8, 120); // 年間金額
inputSheet.getRange("F2:H" + lastRow).setNumberFormat("#,##0");
inputSheet.getRange("D2:E" + lastRow).setWrap(true); // 長いテキストは折り返して全体表示
// 枠線を引く
inputSheet.getRange(1, 1, lastRow, 8).setBorder(true, true, true, true, true, true);
// 入力シートをアクティブにする
ss.setActiveSheet(inputSheet);
if (isFromMenu) {
if (isUpdate) {
SpreadsheetApp.getUi().alert(
'完了',
'入力シートを最新化しました!\n入力されていた金額や回数、メモはそのまま引き継がれています。',
SpreadsheetApp.getUi().ButtonSet.OK
);
} else {
SpreadsheetApp.getUi().alert(
'完了',
'あなた専用の入力シートを作成しました!\n\n【重要】\n単価を入力し、「回数/年」がご家庭の実態と合っているか確認・変更してください。\n(例:ボーナスが年1回なら2→1に変更、水道代が毎月請求なら6→12に変更など)',
SpreadsheetApp.getUi().ButtonSet.OK
);
}
}
}
/**
* 入力シートから集計表シートを生成する
*/
function generateSummarySheet() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const inputSheet = ss.getSheetByName('入力シート');
if (!inputSheet) {
SpreadsheetApp.getUi().alert('エラー', '「入力シート」が見つかりません。先に作成してください。', SpreadsheetApp.getUi().ButtonSet.OK);
return;
}
let summarySheet = ss.getSheetByName('家計調査票(集計)');
if (!summarySheet) {
summarySheet = ss.insertSheet('家計調査票(集計)');
} else {
summarySheet.clear();
}
const data = inputSheet.getDataRange().getValues();
if (data.length <= 1) return;
// ヘッダー除外
const rows = data.slice(1);
// データの集計用オブジェクト
let summary = {
収入: { 世帯主: 0, 配偶者: 0, 家族: 0, 共通: 0, 詳細: [] },
固定費: { 詳細: [], 合計: 0 },
変動費: { 詳細: [], 合計: 0 },
貯蓄: { 詳細: [], 合計: 0 },
資産: { 詳細: [], 合計: 0 }
};
rows.forEach(row => {
let [target, mainCat, subCat, itemName, userMemo, price, times, annual] = row;
annual = Number(annual) || 0;
if (annual === 0) return; // 0円のものは集計に含めない
// メモ欄に記入があれば「項目名 (メモ)」の形で出力、なければ項目名のみ
const memo = userMemo ? `${itemName} (${userMemo})` : itemName;
if (mainCat === "収入") {
if (summary.収入[target] !== undefined) {
summary.収入[target] += annual;
} else {
summary.収入.共通 += annual;
}
summary.収入.詳細.push({ target, subCat, memo, annual });
} else if (summary[mainCat]) {
summary[mainCat].合計 += annual;
summary[mainCat].詳細.push({ target, subCat, memo, annual });
}
});
// === 描画ロジック ===
// 左カラム(固定費・変動費)と右カラム(収入・貯蓄・資産)に分けて描画
let leftRow = 6;
let rightRow = 6;
// --- タイトル ---
summarySheet.getRange("B2:H2").merge().setValue("家計調査票(現在地・年間予測)").setFontSize(16).setFontWeight("bold").setHorizontalAlignment("center");
summarySheet.getRange("B2:H2").setBackground("#eeeeee");
// --- サマリー (年間支出合計・年間収支予測) ---
const totalExp = summary.固定費.合計 + summary.変動費.合計;
const totalInc = summary.収入.世帯主 + summary.収入.配偶者 + summary.収入.家族 + summary.収入.共通;
const balance = totalInc - totalExp - summary.貯蓄.合計;
// 年間支出 合計 (B4:C4 を結合、D4 に金額)
summarySheet.getRange("B4:C4").merge().setValue("年間支出 合計").setFontWeight("bold").setBackground("#ea9999");
summarySheet.getRange("D4").setValue(totalExp).setNumberFormat("#,##0").setFontWeight("bold").setBackground("#ea9999");
summarySheet.getRange("B4:D4").setBorder(true, true, true, true, true, true);
// 年間収支予測 (F4:G4 を結合、H4 に金額)
summarySheet.getRange("F4:G4").merge().setValue("年間収支予測 (収入 - 支出 - 貯蓄)").setFontWeight("bold").setBackground("#ffe599");
summarySheet.getRange("H4").setValue(balance).setNumberFormat("#,##0").setFontWeight("bold").setBackground("#ffe599");
summarySheet.getRange("F4:H4").setBorder(true, true, true, true, true, true);
// ヘルパー関数:ブロックを描画して次の行番号を返す
function drawBlock(sheet, startRow, startCol, title, total, details, isIncome) {
let r = startRow;
// ヘッダー
sheet.getRange(r, startCol, 1, 3).merge().setValue(title).setBackground("#4a86e8").setFontColor("white").setFontWeight("bold");
r++;
// 詳細
if (details.length === 0) {
sheet.getRange(r, startCol).setValue("データなし");
r++;
} else {
details.forEach(d => {
sheet.getRange(r, startCol).setValue(isIncome ? d.target : d.subCat);
sheet.getRange(r, startCol + 1).setValue(d.memo);
sheet.getRange(r, startCol + 2).setValue(d.annual).setNumberFormat("#,##0");
r++;
});
}
// 合計
sheet.getRange(r, startCol, 1, 2).merge().setValue(title + " 合計").setFontWeight("bold").setBackground("#f3f3f3");
sheet.getRange(r, startCol + 2).setValue(total).setNumberFormat("#,##0").setFontWeight("bold").setBackground("#f3f3f3");
// 罫線
sheet.getRange(startRow, startCol, (r - startRow) + 1, 3).setBorder(true, true, true, true, true, true);
return r + 2;
}
// --- 左カラム:支出 ---
leftRow = drawBlock(summarySheet, leftRow, 2, "■ 固定費", summary.固定費.合計, summary.固定費.詳細, false);
leftRow = drawBlock(summarySheet, leftRow, 2, "■ 変動費", summary.変動費.合計, summary.変動費.詳細, false);
// 支出合計は上部に移動したため、ここでは何もしない
// --- 右カラム:収入・貯蓄・資産 ---
rightRow = drawBlock(summarySheet, rightRow, 6, "■ 収入", totalInc, summary.収入.詳細, true);
rightRow = drawBlock(summarySheet, rightRow, 6, "■ 貯蓄(年間フロー)", summary.貯蓄.合計, summary.貯蓄.詳細, false);
rightRow = drawBlock(summarySheet, rightRow, 6, "■ 資産(現在のストック)", summary.資産.合計, summary.資産.詳細, false);
// 収支予測は上部に移動したため、ここでは何もしない
// 見た目の調整
summarySheet.setColumnWidth(1, 20); // 余白
summarySheet.setColumnWidth(2, 100);
summarySheet.setColumnWidth(3, 250); // C列 (項目名+メモ)
summarySheet.setColumnWidth(4, 100);
summarySheet.setColumnWidth(5, 40); // 隙間
summarySheet.setColumnWidth(6, 100);
summarySheet.setColumnWidth(7, 250); // G列 (項目名+メモ)
summarySheet.setColumnWidth(8, 100);
ss.setActiveSheet(summarySheet);
SpreadsheetApp.getUi().alert('完了', '美しい家計調査票(集計表)が完成しました!\n右下の「年間収支予測」がプラスになっているか確認しましょう。', SpreadsheetApp.getUi().ButtonSet.OK);
}
/**
* チェックボックスがクリックされたときに自動実行されるトリガー
* スマホ・タブレットからの実行に対応するため、メニュー以外からも実行できるようにする
*/
function onEdit(e) {
if (!e) return;
const sheet = e.source.getActiveSheet();
// 問診票シートのみで動作
if (sheet.getName() === '問診票') {
// チェックボックスがTRUE(オン)になった時だけ
if (e.value === "TRUE") {
// 編集されたセル(チェックボックス)の右隣のテキストを取得
const textCell = sheet.getRange(e.range.getRow(), e.range.getColumn() - 1);
const text = textCell.getValue();
// 左隣のテキストが「完了」という文字を含んでいるか判定
if (String(text).indexOf("完了") !== -1) {
// メッセージ出力用の右隣のセル(D列)を取得
const statusCell = sheet.getRange(e.range.getRow(), e.range.getColumn() + 1);
// 実行中のステータスを表示
statusCell.setValue("🔄 入力シートを自動生成中...");
SpreadsheetApp.flush(); // 画面を更新して文字を表示させる
// UIを出さないモード(isFromMenu = false)で実行
generateInputSheetFromIntake(false);
// チェックを外して完了メッセージに変更
e.range.setValue(false);
statusCell.setValue("✅ 生成完了!");
}
}
}
}
※ 上記アコーディオン内のコードをコピーしてスプレッドシートの「拡張機能 > Apps Script」に貼り付けるか、ダウンロードしたテキストファイルから直接コピーしてご使用ください。
この家計調査票は、
「家計管理の第一歩である『現在地の可視化』のハードルを極限まで下げたい」
という思いから開発しました。ぜひご活用ください!