为什么onChange和onEdit同时触发?

Asi*_*sim 2 triggers google-sheets google-apps-script

我现在有一个电子表格,我想:

  • 跟踪某人是否已更改已具有值的单元格中的值
  • 跟踪某人在没有值的单元格中添加新值
  • 跟踪某人删除单元格中的值

现在,当我测试install-triggers甚至onEdit()和onChange()时,我只是不明白为什么每当我更改值或在空白单元格上添加新值时都会触发.

你可以在这里看到我的代码:

function onEdit(e){
  Browser.msgBox('EDIT')
}
// trigger --> change
function onmychange(e){
 Browser.msgBox('CHANGE')
}
Run Code Online (Sandbox Code Playgroud)

如果我用值编辑一个单元格并将其更改为其他内容,则两者都会被触发如果我在新单元格中写入内容,则两者都被触发

我的触发器:onmychange - > on spreadsheet - > on change

为什么两个都被炒了?

小智 6

正如文档所述,"on change"触发器包括EDIT以及其他类型的更改:

更改类型(EDIT,INSERT_ROW,INSERT_COLUMN,REMOVE_ROW,REMOVE_COLUMN,INSERT_GRID,REMOVE_GRID,FORMAT或OTHER)

如果您想在更改是编辑时不执行代码,请使用诸如的条件

function onmychange(e) {
  if (e.changeType != "EDIT") {
    Browser.msgBox("Change that is not an edit");
  }
}
Run Code Online (Sandbox Code Playgroud)

也就是说,您提到的所有操作(在已经有值的单元格中更改值,在没有值的单元格中添加NEW值,在单元格中删除值)都是编辑,因此onEdit是您需要的唯一触发器.

如果目标是找到进行了哪种编辑,请使用e.valuee.oldValue.使用简单触发器时前者有些怪癖onEdit(e):

  1. 如果用户直接输入"foo"(包括从外部源粘贴):e.value是"foo"
  2. 如果用户粘贴从工作表中其他位置复制的"foo":e.value是{}空对象.
  3. 如果用户清除之前具有"foo"的单元格:e.value是对象 {"oldValue":"foo"}

(如果使用在编辑时运行的可安装触发器,则在情况2和3中,事件对象中根本没有属性"value".)

为了解决上述问题,我使用以下方法:

function onEdit(e) {
  var newValue = (typeof e.value == "object" ? e.range.getValue() : e.value); 
  //
} 
Run Code Online (Sandbox Code Playgroud)

这确保了newValue具有现在在单元格中的新值.

您可能希望使用以下日志记录触发器来观察触发器的行为:

function onEdit(e) {
  e.range.offset(0, 1).setValue(JSON.stringify(e));
}
Run Code Online (Sandbox Code Playgroud)