打開蘋果的APP Store或者安卓的Google Play商店,去搜尋記帳軟體會發現,玲瑯滿目的各種免費但是不好用,付費又很難做客製化的軟體,以及把你的消費資訊提供給不知名的APP廠商?是不是有種心理疙瘩過不去的檻?這篇工具文章將紀錄,如何使用AI的過程來快速開發一個屬於自己的記帳軟體。建議收藏這篇文章,找個有空閑的時間來實作體驗。
我希望這系列文章能夠實用,讓就算不是資訊背景的普羅大眾也能向AI問懂提示詞,實做出一個屬於自己的客製化系統。基本上,示範使用Google Sheet加上利用AI寫APP Script來完成,過程不會很困難並且能夠快速完成上手。如果你還沒有Google Account,請先完成Google的帳號申請,如果沒有訂閱Google Gemini Pro的,也不用太擔心,我這邊也將步驟完成程式碼節錄下來。
一、把開發需求提交給Gemini
請準備好你的Gemini和Google Sheet我們開始。

首先,你要在Gemini發問,讓他回復你答案。
我想利用google sheet開發一個記帳系統我們先看一下Gemini的回覆是否符合需求:
Google Sheets 記帳系統開發步驟
1. 設計基礎架構
• 建立「流水帳」分頁:欄位包含日期、項目、類別、金額、支付方式。
• 建立「類別設定」分頁:定義支出與收入的分類,供下拉選單使用。
2. 資料驗證 (下拉選單)
• 在流水帳的「類別」欄位使用「資料驗證」,引用「類別設定」分頁的內容。
3. 建立統計報表
• 使用 `SUMIFS` 依月份/類別加總。
• 使用 `QUERY` 函數製作自動更新的彙整表。
4. 手機端輸入優化
• 建立 Google 表單 (Forms) 並連結至此試算表。
5. 視覺化圖表
• 製作每月支出比例圓餅圖。
• 製作收支趨勢折線圖。
在系統開發的過程中,講清楚需求是件非常重要的事。
在這邊先停一下,可以看到AI回覆的內容是針對個人的記帳。但是,我所希望的並不是個人的記帳系統,而是可以讓全家人都能利用的系統,只需要一次性開發就能讓全家人用。
跟著需求,循序漸進,進行以下發問:
我需要開發針對全家人的記帳系統 請在流水帳分頁的欄位中新增消費者欄位定義
類別設定中 如何定義收入跟支出的分類?
Gemini的回覆:
以下是具體的實作建議:
1. 流水帳分頁 (新增消費者欄位)
在原本的欄位中插入一欄 「消費者」(或「成員」)。
欄位順序建議: 日期 | 項目 | 類別 | 金額 | 消費者 | 支付方式 | 備註。
優點: 這樣你以後可以透過篩選或 QUERY 公式,一秒看出「這個月誰花最多」或「各成員的支出佔比」。
2. 類別設定中如何定義「收入」與「支出」?
為了方便管理,建議在「類別設定」分頁採用以下兩種方式之一:
方案 A:分兩欄列出 (最推薦,適合製作下拉選單)
A 欄 (支出類別): 食、衣、住、行、育、樂。
B 欄 (收入類別): 薪資、獎金、投資。
C 欄 (成員名單): 爸爸、媽媽、大寶。
這樣你在流水帳設定「資料驗證」時,可以針對不同情況引用不同範圍。
方案 B:類型標記法 (適合進階分析)
A 欄 (類別): 餐飲、交通、薪水。
B 欄 (類型): 支出、支出、收入。
這種做法在使用公式加總時,可以很方便地用 SUMIFS 區分正負值。
💡 小提醒
既然是全家人使用,強烈建議建立一個 Google 表單 (Forms),在表單中新增一個問題:「是誰花的?」並設定為必填。這樣家人在外面隨手記帳時,系統就會自動幫你填好「消費者」欄位,省去你事後核對的時間!
進行以下發問:
針對項目的定義是什麼?
Gemini的回覆:
在記帳系統中,「項目」(Item) 的定義是:該筆交易的具體描述或細節。
如果「類別」是這筆錢的「歸類」(大方向),那麼「項目」就是這筆錢的「名字」(具體內容)。
🔍 項目 vs. 類別:差別在哪?
為了讓你的系統好分析,這兩者的區分非常重要:

如何定義好的「項目」?
在全家人共用的系統中,項目欄位若寫得好,未來在對帳時會省去很多麻煩。以下是幾個定義建議:
1. 具體化描述(不要只寫「買東西」)
❌ 壞示範: 類別:餐飲 / 項目:晚餐
✅ 好示範: 類別:餐飲 / 項目:石二鍋 (天母店)
為什麼? 日後如果你想回顧哪家餐廳 CP 值高,或是哪天吃了什麼,具體名稱才有意義。
2. 標註數量或期間(特別是固定支出)
❌ 壞示範: 類別:住 / 項目:電費
✅ 好示範: 類別:住 / 項目:1-2 月電費 (台電)
為什麼? 這能讓你快速對比去年的同一時期,支出是否有異常。
3. 備註關鍵細節
❌ 壞示範: 類別:育兒 / 項目:玩具
✅ 好示範: 類別:育兒 / 項目:大寶生日禮物 (樂高)
為什麼? 既然有「消費者」欄位,項目中標註「為了誰」或「什麼目的」會讓帳目更有溫度。
我要求Gemini調整一下欄位順序,讓資料整理更容易。
調整一下資料欄位順序 改為 日期 | 成員 | 類別 | 項目 | 金額 | 支付方式 | 備註

問到這裡,差不多資料欄位定義的雛型就能確定了。
二、建立Google Sheet資料庫與定義類別欄位
我們需要開啟Google Sheet把預想的欄位依序輸入進去,流水帳分頁下將首列名稱依序輸入,這邊會建議進行 凍結第一列 與 欄位置中 粗體字 建議。

並且開啟 第二分頁 並命名為 類別設定 為以下。

內容部分不能照抄,你得自己有自己的定義,以下範例參考。成員名單甚至可以直接寫暱稱或本名,更容易在報表中辨識。

個人建議:儘可能精簡支出大類,把每項目的定義搞清楚,並確定家庭成員有相同的共識,儘可能讓輸入資料時不要出錯。
餐飲:所有吃喝項目都屬於這項。
生活日用品:所有日用消費都屬於這項目,包含蔬果 日用品 文具 消耗品 雜貨。
固定支出:房租 水電 瓦斯 網路費 手機費 管理費 月繳年繳的停車費 規費 稅。
交通:公車 捷運 火車 高鐵 汽車加油。
娛樂:觀光旅遊支出 電影 交際費用。
育兒:跟大寶二寶有關的所有支出項目 奶粉錢 尿布錢 學費。
其他:所有例外在這裡。
我把我個人開發的範例留在這裡:

支付設定的方式應該多數人是固定的,可以開這個欄位紀錄一下。
三、讓Gemini開發應用
接下來是關鍵的一步,複製你的Google Sheet連結給Gemini,並且要求他參照你的類別進行開發。


再次重申,請不要抄我的連結(你要貼你自己定義的Google Sheet連結),抄我連結那是沒有用的,因為我的連結是私有的。
1. 後端程式碼 (Code.gs)
請將原本的 Code.gs 內容替換為以下代碼。這裡新增了 getSettings() 函式,專門用來抓取「類別設定」中的四個欄位 。
function doGet() {
return HtmlService.createHtmlOutputFromFile('Index')
.setTitle('家庭記帳系統 - 動態版')
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL)
.addMetaTag('viewport', 'width=device-width, initial-scale=1');
}
// 抓取試算表中的所有設定值
function getSettings() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName("類別設定");
const data = sheet.getDataRange().getValues();
// 排除標題列,並過濾掉空白儲存格
const expenseCats = data.slice(1).map(row => row[0]).filter(String); // 支出類別
const incomeCats = data.slice(1).map(row => row[1]).filter(String); // 收入類別
const members = data.slice(1).map(row => row[2]).filter(String); // 成員名單
const payments = data.slice(1).map(row => row[3]).filter(String); // 支付設定
return {
expense: expenseCats,
income: incomeCats,
members: members,
payments: payments
};
}
function processForm(formObject) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName("流水帳");
sheet.appendRow([
formObject.date,
formObject.member,
formObject.category,
formObject.item,
formObject.amount,
formObject.payment,
formObject.remarks
]);
return "成功記錄!";
}
2. 前端網頁 (Index.html)
此版本會在網頁載入時自動跟試算表索取最新清單,並根據你選擇「支出」或「收入」動態切換類別選單。
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body { background-color: #f1f3f5; padding: 20px; }
.container { max-width: 500px; background: white; padding: 30px; border-radius: 20px; box-shadow: 0 10px 25px rgba(0,0,0,0.05); }
.loading-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255,255,255,0.8); display: flex; justify-content: center; align-items: center; z-index: 1000; }
</style>
</head>
<body>
<div id="loading" class="loading-overlay"><div>⚙️ 正在同步雲端設定...</div></div>
<div class="container">
<h3 class="text-center mb-4">💰 家庭記帳輸入</h3>
<form id="accountingForm">
<div class="mb-3">
<label class="form-label d-block">收支類型</label>
<div class="btn-group w-100" role="group">
<input type="radio" class="btn-check" name="type" id="typeExp" value="expense" checked onchange="updateCategories()">
<label class="btn btn-outline-danger" for="typeExp">支出</label>
<input type="radio" class="btn-check" name="type" id="typeInc" value="income" onchange="updateCategories()">
<label class="btn btn-outline-success" for="typeInc">收入</label>
</div>
</div>
<div class="mb-3">
<label class="form-label">日期</label>
<input type="date" class="form-control" name="date" id="dateInput" required>
</div>
<div class="mb-3">
<label class="form-label">成員</label>
<select class="form-select" name="member" id="memberSelect" required></select>
</div>
<div class="mb-3">
<label class="form-label">類別</label>
<select class="form-select" name="category" id="categorySelect" required></select>
</div>
<div class="mb-3">
<label class="form-label">項目</label>
<input type="text" class="form-control" name="item" placeholder="細節內容" required>
</div>
<div class="mb-3">
<label class="form-label">金額</label>
<input type="number" class="form-control" name="amount" required>
</div>
<div class="mb-3">
<label class="form-label">支付方式</label>
<select class="form-select" name="payment" id="paymentSelect" required></select>
</div>
<div class="mb-3">
<label class="form-label">備註</label>
<textarea class="form-control" name="remarks" rows="2"></textarea>
</div>
<button type="submit" class="btn btn-primary w-100 btn-lg">確認送出</button>
</form>
<div id="output" class="mt-3 text-center text-primary fw-bold"></div>
</div>
<script>
let allSettings = {};
window.onload = function() {
document.getElementById('dateInput').valueAsDate = new Date();
// 向 GAS 請求設定資料
google.script.run.withSuccessHandler(function(settings) {
allSettings = settings;
populateDropdown('memberSelect', settings.members);
populateDropdown('paymentSelect', settings.payments);
updateCategories(); // 初始化類別選單
document.getElementById('loading').style.display = 'none';
}).getSettings();
};
function populateDropdown(id, list) {
const select = document.getElementById(id);
select.innerHTML = list.map(item => `<option value="${item}">${item}</option>`).join('');
}
// 根據收支類型動態切換類別
function updateCategories() {
const type = document.querySelector('input[name="type"]:checked').value;
const list = type === 'expense' ? allSettings.expense : allSettings.income;
populateDropdown('categorySelect', list);
}
document.getElementById('accountingForm').addEventListener('submit', function(e) {
e.preventDefault();
const btn = e.target.querySelector('button');
btn.disabled = true;
btn.innerHTML = '傳送中...';
google.script.run.withSuccessHandler(function(msg) {
document.getElementById('output').innerHTML = msg;
document.getElementById('accountingForm').reset();
document.getElementById('dateInput').valueAsDate = new Date();
updateCategories();
btn.disabled = false;
btn.innerHTML = '確認送出';
}).processForm(this);
});
</script>
</body>
</html>
接下來要複製後端程式碼與前端程式碼到App Script中。

把原本的gs程式碼砍掉,用Gemini生成的程式碼完全覆蓋。

然後,新增一個前端HTML,檔名必須是Index:

接著一樣,刪除內文,用Gemini提供的HTML蓋掉。

四、佈署與啟用
Gemini會提供一下資訊告訴你如何佈署。
要注意!更版或程式碼修正,需要 重新部署 這個動作,不能省略,只有存擋是沒用的。
如何啟用?
- 在 Apps Script 點擊 「部署」>「新增部署」。
- 類型選擇 「網頁應用程式」。
- 存取權設為 「任何人」 即可。
這套代碼完全符合你目前「類別設定」分頁中的四欄式架構(支出類別、收入類別、成員名單、支付設定)。如果有任何新的分類需要增加,你只需在 Google Sheets 的該欄位下方填入新名稱,網頁重新整理後就會立刻出現!


必須授予存取權,然後選擇Advanced。

同意讓這隻應用來存取。

按 Continue 繼續。

接下來他會給你一個第一版的網頁(按下面連結的複製),讓你輸入資料看看。
在網頁上貼上複製網址,當你看到以下畫面的時候,就代表已成功。

五、測試與確認資料寫入
開發完畢當然要測試一下,直接拿來用,實際輸入看看數值,是否數據有真實寫入資料庫。

APP 會反饋真實有 [成功紀錄!] 的字眼,然後我們需要到資料庫去驗證數據有沒有進去。

當你在流水帳分頁,看到數據實際進入時,就代表系統已正常運作。相信你體驗到這裡已經有感受到Gemini的強大,他在跟 Google Woskspace 做相關聯應用時,幾乎不會出錯。
這會是個系列串文,因為到目前為止,只有基礎的輸入功能,財務報表跟應用優化和延伸都還沒有列入文章中,將會在後續文章中做說明,有興趣的可以跟這一列串文。
免責聲明:由於本人是資訊工程師背景,基本上Script語法與基礎的HTML和CSS閱讀都很容易。使用AI來做系統開發最大的好處是,可以利用 雛型法(Prototyping) 反覆驗證功能和需求可行性,因為AI不是人,所以他們不會靠北...。如果你有遇到錯誤,你也可以請Gemini幫你排除。
如果你還是覺得很難,或者遇到困難,可以在這篇文章下留言,我會儘量回覆。



















