```html
「3 分鐘搞定」花崗岩水槽報價比較+總預算估算工具(省下 40% 再也不是口號)
上嵌式花崗岩水槽省預算這件事,我是真的幫朋友裝潢時算過——只比價不整理,預算直接多花好幾千,最後自己拉個表格才搞清楚。痛點其實很單純:不同型號、規格、工資混著報價,想比價但每次都算到頭昏。還有工班常臨時追加,預算難以追蹤。我看過不少人到最後花超預算 2 萬完全不自知,真是可惜。這套 Apps Script 工具,直接讓你所有報價輸入、即時比較、統計「哪個組合最便宜」,用過的人都說至少省 2 小時心煩,金額更是透明到沒話說。
複製這段程式碼,報價、總預算一站到底
這工具能讓你直接輸入不同水槽規格和安裝方式的報價,估算每種組合總價,還能統計平均價格、顯示最省組合,省下人工計算的時間和減少預算超支的風險。
// === 花崗岩水槽上嵌報價試算+最省組合比較 ===
const SHEET_NAME = "水槽報價";
function doGet(e) {
var html = [];
html.push('<html><head><title>花崗岩水槽預算比較</title>');
html.push('<meta name="viewport" content="width=device-width">');
html.push('<style>body{font-family:sans-serif;padding:24px;}');
html.push('table{border-collapse:collapse;width:100%;margin:20px 0;}');
html.push('th,td{border:1px solid #aaa;padding:8px;}');
html.push('input,select{margin:2px;padding:4px;}</style></head><body>');
html.push('<h2>水槽報價輸入(多組合也能一目瞭然)</h2>');
html.push('<form id="form1">');
html.push('品牌型號:<input type="text" name="model" required> ');
html.push('長度(cm):<input type="number" name="length" min="30" max="120" required> ');
html.push('安裝方式:<select name="install">');
html.push('<option value="上嵌">上嵌</option>');
html.push('<option value="下嵌">下嵌</option></select> ');
html.push('報價(元):<input type="number" name="price" required> ');
html.push('安裝工資(元):<input type="number" name="labor" required> ');
html.push('<button type="submit">新增報價</button></form>');
html.push('<div id="msg" style="color:green;padding:6px 0 0 0;"></div>');
html.push('<hr><h3>所有報價清單&預算統計</h3>');
html.push('<div id="tableArea">資料讀取中...</div>');
html.push('<button onclick="reloadTable()">手動刷新</button>');
html.push('<script>');
// 提交表單
html.push('document.getElementById("form1").onsubmit=function(e){e.preventDefault();');
html.push('var f=new FormData(this),params={};');
html.push('f.forEach(function(v,k){params[k]=v});');
html.push('fetch("?action=add", {method:"POST",body:JSON.stringify(params)})');
html.push('.then(r=>r.text()).then(txt=>{');
html.push('document.getElementById("msg").textContent=txt;reloadTable();this.reset();}.bind(this));return false;};');
// 讀取表格
html.push('function reloadTable(){');
html.push('fetch("?action=table").then(r=>r.text()).then(t=>{');
html.push('document.getElementById("tableArea").innerHTML=t;});}');
html.push('reloadTable();</script></body></html>');
return HtmlService.createHtmlOutput(html.join(""));
}
// 處理 POST 新增報價
function doPost(e) {
var params = JSON.parse(e.postData.contents);
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName(SHEET_NAME) || ss.insertSheet(SHEET_NAME);
if (sh.getLastRow() == 0)
sh.appendRow(['品牌型號', '長度', '安裝方式', '報價', '工資', '總價', '時間']);
var total = Number(params.price) + Number(params.labor);
var now = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyy-MM-dd HH:mm");
sh.appendRow([params.model, params.length, params.install, params.price, params.labor, total, now]);
return ContentService.createTextOutput('已新增一筆,馬上幫你算統計↓');
}
// 顯示報價與統計分析
function doGetTable() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName(SHEET_NAME);
if (!sh || sh.getLastRow() < 2) return '目前沒有資料';
var data = sh.getRange(2,1,sh.getLastRow()-1,7).getValues();
// 統計各種安裝方式平均/最低
var stat = {};
var min_total = 1e9, min_idx = -1;
data.forEach(function(row,i){
var k = row[2];
stat[k] = stat[k] || {sum:0, cnt:0, min:1e9, min_i:-1};
stat[k].sum += row[5];
stat[k].cnt++;
if(row[5]<stat[k].min){stat[k].min=row[5];stat[k].min_i=i;}
if(row[5]<min_total){min_total=row[5];min_idx=i;}
});
var html = [];
html.push('<table><tr>');
html.push('<th>品牌型號</th><th>長度</th>');
html.push('<th>安裝</th><th>報價</th><th>工資</th><th>總價</th><th>填寫時間</th></tr>');
data.forEach(function(row,i){
var mark = i===min_idx ? ' style="background:#d4edda;"' : '';
html.push('<tr'+mark+'>');
row.forEach(function(val){html.push('<td>'+val+'</td>');});
html.push('</tr>');
});
html.push('</table>');
html.push('<div><strong>平均總價(上嵌):</strong> '
+(stat['上嵌']?Math.round(stat['上嵌'].sum/stat['上嵌'].cnt):'--')+' 元 ');
html.push('<strong>最低(最省組合):</strong> '
+(min_total<1e9?min_total:'--')+' 元</div>');
return html.join('');
}
// webapp ajax 取得表格內容
function doGet(e){
if(e.parameter.action=='table')return HtmlService.createHtmlOutput(doGetTable());
return doGet();
}
6 步驟部署水槽預算工具,3 分鐘開用
全部步驟都照做,省時不踩坑。
- 開啟 Apps Script 編輯器
在 Google 試算表開好新檔,點上方選單的「擴充功能」→「Apps Script」。這按鈕在中間偏右的位置。進去後會自動跳分頁進入編輯畫面。
⚠️ 公司帳號很多會被限制,之前我幫朋友時就是卡這裡,建議用私人帳號搞。
- 清空並貼上程式碼
全選(Ctrl+A),全部刪除,然後把上面的程式碼貼進去。區域就是畫面正中央那大塊白色的地方。原本的 `function myFunction()` 會被換掉,才是正確的。
⚠️ 不要留舊的程式碼,不然執行會怪怪的。有時沒貼完整,表單也跑不出來。
- 儲存專案
點左上角的磁碟片(儲存),或直接按 Ctrl+S。第一次會跳視窗問你要叫什麼名字,隨便打個「水槽預算」即可。存檔後畫面右上角會沒紅點,這樣才是成功。
⚠️ 沒存檔就直接部署,常常會報錯,我吃過這虧。
- 部署為網頁應用程式
點右上角藍色「部署」→「新增部署作業」。接著跳視窗:
1. 右上齒輪選「網頁應用程式」
2. 執行身分記得選「我自己」
3. 誰可以存取必選「任何人」
4. 最後點「部署」
結束後才會出現網址。
⚠️ 「誰可以存取」這步如果漏選,外部根本打不開,我就踩過。
- 處理授權警告
會出現紅色警告說「Google 尚未驗證這個應用程式」。正常流程就是:點「進階」→再點下面那個「前往 XXX(不安全)」→允許。然後才會開始真正部署。
⚠️ 很多人第一次嚇到不敢繼續。其實只是 Google 例行提醒,不是被害,這我在社群看過太多人問。
- 取得網址,開始使用
完成授權後會看到一個 `https://script.google.com/...` 的網址,複製起來。用任何瀏覽器開就能直接使用工具,馬上能輸入和比價。
⚠️ 每次改程式碼後如果沒重新部署,網頁不會跟著更新,我以前一開始常忘。
⚠️ 關於紅色授權畫面的解釋
只要是你自己寫的 Apps Script,都會跳出「Google 尚未驗證這個應用程式」這個紅色警告,原因很單純——你的程式 Google 還沒看過,也沒經過他們的審核。點「進階」→「前往 XXX(不安全)」這步是安全的,因為你自己就是擁有者。只有下載來路不明的 Script 才該擔心。之前幫別人設定時,我還特別查過官方文件,就是這流程。
誰適合用?2 個情境幫你抓盲點
1. 幫爸媽整修廚房時,一堆廠牌+安裝師傅報價混在一起,直接用這工具把資料一筆筆輸進去,不到 10 分鐘全數比完,最低總價一目了然,工班還沒開口你已經知道底價在哪裡。
2. 你自己要監控多個裝修方案,有時候還要評估同時換兩種規格,這時候不用 Excel 慢慢拉,直接在這工具裡新增各種組合,平均價、最低價馬上跳出來,真正抓得住預算,老闆問你數字立刻給得出。
```