はじめに
月別切り替え・円グラフ・予算設定に続き、今回は固定費の自動追加機能を実装しました。
【シンプル家計簿】https://kakeibo-khaki.vercel.app/
毎月発生する家賃・光熱費・サブスクなどを手動で入力する手間をなくすことが目的です。
追加した機能
固定費設定画面(fixedcost.html)
- 名前・カテゴリ・金額・種別・毎月何日を登録
- 登録済み一覧表示・削除機能
- データは
kakeibo_fixedキーでlocalStorageに保存
index.htmlの自動追加ロジック
- アプリ起動時に
applyFixedCosts()を実行 - 指定日を過ぎていて当月未追加なら自動追加
- 固定費には🔁固定バッジを表示
- 追加時に4秒間通知を表示
実装の概要
1. データ構造
固定費データは家計簿・予算とは別のキーで管理しています。
// 家計簿データ
localStorage.setItem('kakeibo', JSON.stringify(items));
// 予算データ
localStorage.setItem('kakeibo_budgets', JSON.stringify(budgets));
// 固定費データ(今回追加)
localStorage.setItem('kakeibo_fixed', JSON.stringify(fixedCosts));
// fixedCostsの構造
fixedCosts = [
{ id: 123, name: '家賃', cat: 'その他', amount: 50000, type: 'expense', day: 25 },
{ id: 456, name: '電気代', cat: '光熱費', amount: 8000, type: 'expense', day: 10 },
]
2. 自動追加ロジック
function applyFixedCosts(){
if(fixedCosts.length === 0) return;
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth() + 1;
const todayDay = now.getDate();
const added = [];
fixedCosts.forEach(f => {
// 指定日を過ぎているか確認
if(todayDay < f.day) return;
// 今月の指定日付を作成(例:2026-05-25)
const dateStr = `${year}-${String(month).padStart(2,'0')}-${String(f.day).padStart(2,'0')}`;
// 今月すでに同じ固定費が追加済みか確認
const alreadyAdded = items.some(i =>
i.date === dateStr &&
i.memo === f.name &&
i.cat === f.cat &&
i.amount === f.amount &&
i.type === f.type &&
i.isFixed === true
);
if(!alreadyAdded){
items.unshift({
id: Date.now() + Math.random(),
date: dateStr,
memo: f.name,
cat: f.cat,
amount: f.amount,
type: f.type,
isFixed: true // 固定費フラグ
});
added.push(f.name);
}
});
if(added.length > 0){
save();
// 追加通知を4秒表示
const notice = document.getElementById('fixed-notice');
notice.textContent = `✅ 固定費を自動追加しました:${added.join('・')}`;
notice.style.display = 'block';
setTimeout(()=>{ notice.style.display='none'; }, 4000);
}
}
重複追加を防ぐ仕組み:
isFixed:trueフラグを持つデータで、日付・名前・カテゴリ・金額・種別がすべて一致するものがあれば追加しない。これにより何度アプリを開いても重複しません。
3. 日付のゼロ埋め処理
const dateStr = `${year}-${String(month).padStart(2,'0')}-${String(f.day).padStart(2,'0')}`;
padStart(2,'0')は桁数が足りないときに先頭に0を補完します。
String(5).padStart(2,'0') // → "05"
String(12).padStart(2,'0') // → "12"(そのまま)
2026-5-1ではなく2026-05-01の形式にするために使っています。
4. 起動時の実行順序
// 固定費を追加してから描画する
applyFixedCosts(); // ← 先に固定費を追加
updateMonthLabel();
render(); // ← 追加済みのデータで描画
render()より先にapplyFixedCosts()を呼ぶことで、起動直後から固定費が反映された状態で表示されます。
工夫した点
指定日を過ぎてから開いても追加される
「毎月25日」に設定していて、27日に初めてアプリを開いた場合でも当月分が自動追加されます。todayDay < f.dayのときだけスキップすることで実現しています。
固定費には🔁バッジを表示
${i.isFixed ? '<span style="font-size:10px;color:#1D9E75;margin-left:4px;">🔁固定</span>' : ''}
手動入力と固定費を見分けられるようにしました。
まとめ
| 変更箇所 | 内容 |
|---|---|
| fixedcost.html | 固定費設定専用画面を新規作成 |
| JS変数 |
fixedCostsを追加(localStorageで別管理) |
| JS関数 |
applyFixedCosts()を新規追加 |
| 起動処理 |
render()前にapplyFixedCosts()を呼び出し |
| 一覧表示 | 固定費に🔁バッジを追加 |
次回はCSVエクスポート機能の実装を予定しています。
★開発したアプリ
【シンプル家計簿】https://kakeibo-khaki.vercel.app/
