iT邦幫忙

1

google 試算表 App Scripts 問題

  • 分享至 

  • xImage

想要針對google試算表請教各位大大一些問題,簡單扼要地說是有一個試算表裡有兩個分頁,一個是sheet1另一個是sheet2,想要在sheet1的A1、A2、A3、A4每次變更數字的時候都在sheet2裡記錄什麼時間記錄了什麼數字,未來好拿來做成趨勢線圖現在只記錄了一次就停了,AppScript程式應該要怎麼改?

示意圖:
https://ithelp.ithome.com.tw/upload/images/20251016/20167570aPHN9657gk.png
https://ithelp.ithome.com.tw/upload/images/20251016/20167570ccR2DFbbeV.png
A1、A2、A3、A4已變更為B3、C3、D3、E3

程式碼:
function onEdit(e) {
const sheetName = 'Sheet2';
const logSheetName = 'log';
const targetCells = ['B3', 'C3', 'D3', 'E3'];

if (!e) return;

const sheet = e.range.getSheet();
const row = e.range.getRow();
const column = e.range.getColumn();
const editedCell = sheet.getRange(row, column).getA1Notation();

if (sheet.getSheetName() === sheetName && targetCells.includes(editedCell)) {
const logSheet = e.source.getSheetByName(logSheetName);
if (!logSheet) return;

const timestamp = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), 'yyyy/MM/dd HH:mm');
const valueB = sheet.getRange(6, 2).getValue(); // B6
const valueC = sheet.getRange(6, 3).getValue(); // C6
const valueD = sheet.getRange(6, 4).getValue(); // D6
const valueE = sheet.getRange(6, 5).getValue(); // E6

logSheet.appendRow([timestamp, valueB, valueC, valueD, valueE]);

}
}

-----10/30更新
示意圖:
https://ithelp.ithome.com.tw/upload/images/20251030/20167570u57S525fL2.pnghttps://ithelp.ithome.com.tw/upload/images/20251030/20167570snYj48U2CX.pnghttps://ithelp.ithome.com.tw/upload/images/20251030/20167570vMt7ZCfULZ.png
程式完成
function checkAndLogGValues() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName("Sheet1");
var logSheet = ss.getSheetByName("Sheet2");

if (!sourceSheet) {
Logger.log("找不到 Sheet1");
return;
}

if (!logSheet) {
logSheet = ss.insertSheet("Sheet2");
logSheet.getRange(1, 1, 1, 6).setValues([["時間", "G30", "G31", "G32", "G33", "G34"]]);
}

// 讀取 G30:G34 的值
var values = sourceSheet.getRange(30, 7, 5, 1).getValues(); // G = column 7
var g30 = values[0][0];
var g31 = values[1][0];
var g32 = values[2][0];
var g33 = values[3][0];
var g34 = values[4][0];

var timestamp = new Date();
var rowData = [timestamp, g30, g31, g32, g33, g34];

// 寫入 Sheet2 的下一列
var nextRow = logSheet.getLastRow() + 1;
logSheet.getRange(nextRow + 1, 1, 1, 6).setValues([rowData]);
logSheet.getRange(nextRow + 1, 1).setNumberFormat("yyyy/MM/dd HH:mm:ss");
}

看更多先前的討論...收起先前的討論...
win895564 iT邦研究生 4 級 ‧ 2025-10-16 17:53:59 檢舉
程式碼丟出來或是目前有哪些設定大家比較好debug,另外 你有說道只記錄的一次我只能猜測你資料是從其他地方自己帶過來的或是手動key的,那這樣看起來可以去看一下觸發器的部分,當然還是提供多點資料會比較有幫助
資料是用公式帶進sheet2的
win895564 iT邦研究生 4 級 ‧ 2025-10-17 17:34:13 檢舉
看了你後面傳的程式碼,這樣看起來好像跟你原先說的需求有點落差並且似乎又多了一個log表,那目前從你傳的程式碼在看你原先的需求 這樣看起來你要做的應該是 sheet1的b3~e3任一cell資料有更動的話就帶入sheet2 並且記錄當前sheet1的資料還有當下時間。
如果是這樣的話 應該是單純監控sheet1的b3~e3 然後也適用onedit 就相當下b3~e3的資料+當下時間傳入到sheet2 供你參考
嗯...想問一下多一個log表我認為就跟多一個變數差不多的意思這會出現什麼問題嗎?
如果你的意思是,你想要有兩個表都用來log資料,那基本上不會有問題。

原則就是每個表的用途單一;如果會持續擴展的話,建議先筆記清楚資料流向,盡可能保持單一資料流。

例如如果:
- A表=>B表=>C表
- D表=>C表

就盡量不要:
- C表=>A表
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

2
分かるカモ
iT邦新手 5 級 ‧ 2025-10-17 03:02:27
最佳解答

睡前剛好觸及到這篇,只稍微瀏覽、沒實際細測,提供幾個大方向:

1、換個乾淨的環境測試
乍看不覺得是程式碼的問題,驗證的方式很簡單:
你開一份新的試算表,其他邏輯、公式都不要放,只貼上onEdit()
若能正常log,則為其他函式和公式的問題

2、錯誤訊息
你的問題是:第一次觸發,但之後的編輯都不會觸發?
那你第二次「手動」編輯之後,IDE是否有跳錯誤訊息?

3、使用方式與需求通靈
或是更基本的原因
onEdit只會因為user手動編輯觸發
GAS腳本、公式產生的值等等都不會觸發
你的腳本,一格一格一格手動慢慢慢編輯,應該會正常log

但你不是直接log編輯了什麼
那log出來的快照可能因為觸發時機只抓到最後一次的結果

說到底,log編輯紀錄本身才是最穩的做法
如果沒有特殊需求或場景限制
那保留所有編輯過的前後值當歷史紀錄,比保留結果更好管理資料
要跑結果可以再加一個表,讓每個表的功能切分清楚

4、建議
猜不出監聽的欄位會用什麼形式被編輯
也猜不出log的欄位和監聽的欄位的關係
建議下次除了提供程式碼,相關試算表結構、你測過什麼、是否有錯誤訊息也一併附上來
其實通常做完上述的,這種小腳本、小需求就能自己找出問題了

或最乾脆的做法,連同腳本複製一個試算表,去識別化後把有編輯權限的連結附上來,這樣我們就可以直接測、直接改

我要發表回答

立即登入回答