こんなことがありました
「シートの特定のセルが編集されたらそれを検知してSlackに通知してほしい」というニーズがあったので、これのGASを書いたのですが「編集したけど通知が来ない」という連絡がありました。
例えば↓こんな管理表があって「C列が 完了
になったら、その行のタスク名とともにSlackに通知する」みたいな。
↑この状態で、「C3」を「完了」にしたときはSlack通知が来るのですが、
↑こんな感じで「A4:C4という範囲を一気に貼り付ける」をやると、たしかに「C列が更新されている」のではありますが、Slack通知が届きません。
オチとしては、範囲を貼り付けられた場合、下記の「単一セルの編集の検知」だと「貼り付けた範囲の左上のセル」は検知できるのだけどそれ以外のセルはわからない、でした。
「複数セルが同時に編集された時」(範囲を貼り付けられた時)の検知の仕方もメモっておきました。
単一セルの編集の検知
function onEdit(e) {
const ss = e.source;
const sheet = ss.getActiveSheet();
const sheetName = sheet.getName();
const changedRow = e.range.getRow();
const changedCol = e.range.getColumn();
console.log(`[${sheetName}]シートの [${changedRow}]行目、[${changedCol}]列目が [${e.oldValue}] から [${e.value}] に編集された`)
}
複数セルの同時編集の検知
function onEdit(e) {
const editedValues = e.range.getValues();
console.log(editedValues) // 編集された値の二次元配列が取れる
const rowStart = e.range.rowStart;
const rowEnd = e.range.rowEnd;
const colStart = e.range.columnStart;
const colEnd = e.range.columnEnd;
const sheet = SpreadsheetApp.getActive().getActiveSheet()
for (let r = rowStart; r <= rowEnd; r++) {
for (let c = colStart; c <= colEnd; c++) {
const v = sheet.getRange(r, c).getValue()
console.log(`[${sheet.getName()}]シートの [${r}]行目、[${c}]列目 が 「${v}」に編集された`);
}
}
}
このやり方だと 編集前の値 は取れないのかな。なにか方法があるのかな。
参考(というかほぼこれ): GAS入門 スプレッドシートのセル編集時のイベントトリガーまとめ │ Web備忘録