vocus logo

方格子 vocus

限時公開

AI開發:記帳工具快速開發(上)

Wei-avatar-img
發佈於AI開發
更新 發佈閱讀 24 分鐘
打開蘋果的APP Store或者安卓的Google Play商店,去搜尋記帳軟體會發現,玲瑯滿目的各種免費但是不好用,付費又很難做客製化的軟體,以及把你的消費資訊提供給不知名的APP廠商?是不是有種心理疙瘩過不去的檻?這篇工具文章將紀錄,如何使用AI的過程來快速開發一個屬於自己的記帳軟體。建議收藏這篇文章,找個有空閑的時間來實作體驗。

我希望這系列文章能夠實用,讓就算不是資訊背景的普羅大眾也能向AI問懂提示詞,實做出一個屬於自己的客製化系統。基本上,示範使用Google Sheet加上利用AI寫APP Script來完成,過程不會很困難並且能夠快速完成上手。如果你還沒有Google Account,請先完成Google的帳號申請,如果沒有訂閱Google Gemini Pro的,也不用太擔心,我這邊也將步驟完成程式碼節錄下來。

一、把開發需求提交給Gemini

請準備好你的Gemini和Google Sheet我們開始。

raw-image

首先,你要在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. 類別:差別在哪?
為了讓你的系統好分析,這兩者的區分非常重要:
raw-image
如何定義好的「項目」?

在全家人共用的系統中,項目欄位若寫得好,未來在對帳時會省去很多麻煩。以下是幾個定義建議:

1. 具體化描述(不要只寫「買東西」)

❌ 壞示範: 類別:餐飲 / 項目:晚餐
✅ 好示範: 類別:餐飲 / 項目:石二鍋 (天母店)

為什麼? 日後如果你想回顧哪家餐廳 CP 值高,或是哪天吃了什麼,具體名稱才有意義。

2. 標註數量或期間(特別是固定支出)

❌ 壞示範: 類別:住 / 項目:電費
✅ 好示範: 類別:住 / 項目:1-2 月電費 (台電)

為什麼? 這能讓你快速對比去年的同一時期,支出是否有異常。

3. 備註關鍵細節

❌ 壞示範: 類別:育兒 / 項目:玩具
✅ 好示範: 類別:育兒 / 項目:大寶生日禮物 (樂高)

為什麼? 既然有「消費者」欄位,項目中標註「為了誰」或「什麼目的」會讓帳目更有溫度。

我要求Gemini調整一下欄位順序,讓資料整理更容易。

調整一下資料欄位順序 改為 日期 | 成員 | 類別 | 項目 | 金額 | 支付方式 | 備註
raw-image

問到這裡,差不多資料欄位定義的雛型就能確定了。

二、建立Google Sheet資料庫與定義類別欄位

我們需要開啟Google Sheet把預想的欄位依序輸入進去,流水帳分頁下將首列名稱依序輸入,這邊會建議進行 凍結第一列 與 欄位置中 粗體字 建議。

raw-image

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

raw-image

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

raw-image

個人建議:儘可能精簡支出大類,把每項目的定義搞清楚,並確定家庭成員有相同的共識,儘可能讓輸入資料時不要出錯。

餐飲:所有吃喝項目都屬於這項。

生活日用品:所有日用消費都屬於這項目,包含蔬果 日用品 文具 消耗品 雜貨。

固定支出:房租 水電 瓦斯 網路費 手機費 管理費 月繳年繳的停車費 規費 稅。

交通:公車 捷運 火車 高鐵 汽車加油。

娛樂:觀光旅遊支出 電影 交際費用。

育兒:跟大寶二寶有關的所有支出項目 奶粉錢 尿布錢 學費。

其他:所有例外在這裡。

我把我個人開發的範例留在這裡:

raw-image

支付設定的方式應該多數人是固定的,可以開這個欄位紀錄一下。

三、讓Gemini開發應用

接下來是關鍵的一步,複製你的Google Sheet連結給Gemini,並且要求他參照你的類別進行開發。

raw-image
raw-image

再次重申,請不要抄我的連結(你要貼你自己定義的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中。

raw-image

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

raw-image

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

raw-image

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

raw-image

四、佈署與啟用

Gemini會提供一下資訊告訴你如何佈署。

要注意!更版或程式碼修正,需要 重新部署 這個動作,不能省略,只有存擋是沒用的。

如何啟用?

  1. 在 Apps Script 點擊 「部署」>「新增部署」
  2. 類型選擇 「網頁應用程式」
  3. 存取權設為 「任何人」 即可。

這套代碼完全符合你目前「類別設定」分頁中的四欄式架構(支出類別、收入類別、成員名單、支付設定)。如果有任何新的分類需要增加,你只需在 Google Sheets 的該欄位下方填入新名稱,網頁重新整理後就會立刻出現!

raw-image
raw-image

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

raw-image

同意讓這隻應用來存取。

raw-image

Continue 繼續。

raw-image

接下來他會給你一個第一版的網頁(按下面連結的複製),讓你輸入資料看看。

在網頁上貼上複製網址,當你看到以下畫面的時候,就代表已成功。

raw-image

五、測試與確認資料寫入

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

raw-image


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


raw-image

當你在流水帳分頁,看到數據實際進入時,就代表系統已正常運作。相信你體驗到這裡已經有感受到Gemini的強大,他在跟 Google Woskspace 做相關聯應用時,幾乎不會出錯。

這會是個系列串文,因為到目前為止,只有基礎的輸入功能,財務報表跟應用優化和延伸都還沒有列入文章中,將會在後續文章中做說明,有興趣的可以跟這一列串文。

免責聲明:由於本人是資訊工程師背景,基本上Script語法與基礎的HTML和CSS閱讀都很容易。使用AI來做系統開發最大的好處是,可以利用 雛型法(Prototyping) 反覆驗證功能和需求可行性,因為AI不是人,所以他們不會靠北...。如果你有遇到錯誤,你也可以請Gemini幫你排除。

如果你還是覺得很難,或者遇到困難,可以在這篇文章下留言,我會儘量回覆。


留言
avatar-img
Second Half - 下半場
0會員
10內容數
人生下半場,應該不一樣。
你可能也想看
Thumbnail
賽勒布倫尼科夫以流亡處境回望蘇聯電影導演帕拉贊諾夫的舞台作品,以十段寓言式殘篇,重新拼貼記憶、暴力與美學,並將審查、政治犯、戰爭陰影與「形式即政治」的劇場傳統推到台前。本文聚焦於《傳奇:帕拉贊諾夫的十段殘篇》的舞台美術、音樂與多重扮演策略,嘗試解析極權底下不可言說之事,將如何成為可被觀看的公共發聲。
Thumbnail
賽勒布倫尼科夫以流亡處境回望蘇聯電影導演帕拉贊諾夫的舞台作品,以十段寓言式殘篇,重新拼貼記憶、暴力與美學,並將審查、政治犯、戰爭陰影與「形式即政治」的劇場傳統推到台前。本文聚焦於《傳奇:帕拉贊諾夫的十段殘篇》的舞台美術、音樂與多重扮演策略,嘗試解析極權底下不可言說之事,將如何成為可被觀看的公共發聲。
Thumbnail
柏林劇團在 2026 北藝嚴選,再次帶來由布萊希特改編的經典劇目《三便士歌劇》(The Threepenny Opera),導演巴里・柯斯基以舞台結構與舞台調度,重新向「疏離」進行提問。本文將從觀眾慾望作為戲劇內核,藉由沉浸與疏離的辯證,解析此作如何再次照見觀眾自身的位置。
Thumbnail
柏林劇團在 2026 北藝嚴選,再次帶來由布萊希特改編的經典劇目《三便士歌劇》(The Threepenny Opera),導演巴里・柯斯基以舞台結構與舞台調度,重新向「疏離」進行提問。本文將從觀眾慾望作為戲劇內核,藉由沉浸與疏離的辯證,解析此作如何再次照見觀眾自身的位置。
Thumbnail
本文深入解析臺灣劇團「晃晃跨幅町」對易卜生經典劇作《海妲.蓋柏樂》的詮釋,從劇本歷史、聲響與舞臺設計,到演員的主體創作方法,探討此版本如何讓經典劇作在當代劇場語境下煥發新生,滿足現代觀眾的觀看慾望。
Thumbnail
本文深入解析臺灣劇團「晃晃跨幅町」對易卜生經典劇作《海妲.蓋柏樂》的詮釋,從劇本歷史、聲響與舞臺設計,到演員的主體創作方法,探討此版本如何讓經典劇作在當代劇場語境下煥發新生,滿足現代觀眾的觀看慾望。
Thumbnail
《轉轉生》為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,融合舞蹈、音樂、時尚和視覺藝術,透過身體、服裝與群舞結構,回應殖民歷史、城市經驗與祖靈記憶的交錯。本文將從服裝設計、身體語彙與「輪迴」的「誕生—死亡—重生」結構出發,分析《轉轉生》如何以當代目光,形塑去殖民視角的奈及利亞歷史。
Thumbnail
《轉轉生》為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,融合舞蹈、音樂、時尚和視覺藝術,透過身體、服裝與群舞結構,回應殖民歷史、城市經驗與祖靈記憶的交錯。本文將從服裝設計、身體語彙與「輪迴」的「誕生—死亡—重生」結構出發,分析《轉轉生》如何以當代目光,形塑去殖民視角的奈及利亞歷史。
Thumbnail
這不是一篇勸敗文,也不是那種教你如何用 Notion 管理人生的教學指南。 今天想聊的,是那些躺在你 iPad 裡積灰塵的 App,以及我們試圖用數位工具來掩蓋的,關於人性的懶惰與空虛。 這太複雜了,我只是想變有錢 故事得從幾個月前的一封售後服務信說起。 那天下午,我打開電腦,想整理
Thumbnail
這不是一篇勸敗文,也不是那種教你如何用 Notion 管理人生的教學指南。 今天想聊的,是那些躺在你 iPad 裡積灰塵的 App,以及我們試圖用數位工具來掩蓋的,關於人性的懶惰與空虛。 這太複雜了,我只是想變有錢 故事得從幾個月前的一封售後服務信說起。 那天下午,我打開電腦,想整理
Thumbnail
你是不是也曾經興沖沖地買了精美的記帳本,或下載功能齊全的 App,信誓旦旦地說「這次絕對要記帳到底」?結果第一天還興致勃勃地記下每筆開支,第二天開始覺得麻煩,第三天就徹底忘得一乾二淨? 如果這聽起來就是你的故事,別擔心,你絕對不孤單。根據習慣形成的心理學研究,許多人放棄記帳,並非因為缺乏意
Thumbnail
你是不是也曾經興沖沖地買了精美的記帳本,或下載功能齊全的 App,信誓旦旦地說「這次絕對要記帳到底」?結果第一天還興致勃勃地記下每筆開支,第二天開始覺得麻煩,第三天就徹底忘得一乾二淨? 如果這聽起來就是你的故事,別擔心,你絕對不孤單。根據習慣形成的心理學研究,許多人放棄記帳,並非因為缺乏意
Thumbnail
擺脫月光族命運!透過簡單的三欄記帳法,建立個人預算架構,並養成月初財務檢查的習慣,讓存錢不再是壓力,而是通往夢想之路。
Thumbnail
擺脫月光族命運!透過簡單的三欄記帳法,建立個人預算架構,並養成月初財務檢查的習慣,讓存錢不再是壓力,而是通往夢想之路。
Thumbnail
你是否有納悶過,為何周遭朋友或是聽過的例子,很少有人是透過記帳來變有錢?甚至還聽過有人說,富人才不記帳呢!
Thumbnail
你是否有納悶過,為何周遭朋友或是聽過的例子,很少有人是透過記帳來變有錢?甚至還聽過有人說,富人才不記帳呢!
Thumbnail
對於開始學習投資理財的新手,不論是從什麼管道入手,書籍、雜誌、影音、線上還是線下課程,幾乎都會聽到一個建議,就是要「記帳」。 但不管是還沒開始記帳,還是記帳一段時間後,往往會有這樣的疑惑:「記帳也不會讓我的錢變多啊,幹嘛要記?」、「除了感覺自己花了很多錢,好像也什麼功能」。 本篇文章為您解惑。
Thumbnail
對於開始學習投資理財的新手,不論是從什麼管道入手,書籍、雜誌、影音、線上還是線下課程,幾乎都會聽到一個建議,就是要「記帳」。 但不管是還沒開始記帳,還是記帳一段時間後,往往會有這樣的疑惑:「記帳也不會讓我的錢變多啊,幹嘛要記?」、「除了感覺自己花了很多錢,好像也什麼功能」。 本篇文章為您解惑。
Thumbnail
你的錢!去哪了?還記得昨天的花費嗎? 開始理財實驗室後與同事深聊, 才發現多數幾乎沒有記帳的習慣, 一問根本不清楚每天或每月的花費。 平常日常瑣碎要記得的東西那麼多, 常常剛吃完一餐, 一個下午過去,就不記得上一餐吃什麼跟金額, 一天1次,一個月就漏掉30次, 因此對於花費的預算抓不準, 理財計畫
Thumbnail
你的錢!去哪了?還記得昨天的花費嗎? 開始理財實驗室後與同事深聊, 才發現多數幾乎沒有記帳的習慣, 一問根本不清楚每天或每月的花費。 平常日常瑣碎要記得的東西那麼多, 常常剛吃完一餐, 一個下午過去,就不記得上一餐吃什麼跟金額, 一天1次,一個月就漏掉30次, 因此對於花費的預算抓不準, 理財計畫
Thumbnail
為什麼要記帳 首先大家一定都有嘗試過記帳,但是過沒多久就覺得每天紀錄很煩,通常是很難維持下去。但是記帳又很重要,如果你完全不知道自己有多少錢,要怎麼開始實行投資理財計劃呢? 記帳的迷思 記帳不是為了省錢 用記帳來幫助你檢視自己的消費行為,把錢花在刀口上,讓每一分錢發揮出最大價值! 從記帳擬定計劃
Thumbnail
為什麼要記帳 首先大家一定都有嘗試過記帳,但是過沒多久就覺得每天紀錄很煩,通常是很難維持下去。但是記帳又很重要,如果你完全不知道自己有多少錢,要怎麼開始實行投資理財計劃呢? 記帳的迷思 記帳不是為了省錢 用記帳來幫助你檢視自己的消費行為,把錢花在刀口上,讓每一分錢發揮出最大價值! 從記帳擬定計劃
Thumbnail
就像當年的ED不知道存30%要做什麼而不存又會怎樣,那存了又為了什麼的無限無腦循環到後來還是LET IT GO開開去了(花掉月薪了),真的很無腦花的不止是錢還是自己用大量時間跟手破皮流血流汗換來的辛苦月薪,當時的ED每筆花費我都在記帳,記得連我買蛋餅跟三明治以及豆漿的錢我都記下來!
Thumbnail
就像當年的ED不知道存30%要做什麼而不存又會怎樣,那存了又為了什麼的無限無腦循環到後來還是LET IT GO開開去了(花掉月薪了),真的很無腦花的不止是錢還是自己用大量時間跟手破皮流血流汗換來的辛苦月薪,當時的ED每筆花費我都在記帳,記得連我買蛋餅跟三明治以及豆漿的錢我都記下來!
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News