我如何才能 运行 onChange 或 onEdit 在 Google Apps 脚本中仅当在我想要的 sheet 上输入新数据时?

How can I run onChange or onEdit in Google Apps Script only when new data is entered on the sheet I want?

我的电子表格有 3 张。名称是 sheet1、sheet2、sheet3。我有一个函数“onChange()”。我在触发器上安装了 onChange 函数。如果仅在 sheet2 添加新行时,我想要 运行 onChange 函数。但不能正常工作。如果我写 sheet1 或 sheet2 或 sheet3 任何东西总是 运行 我的 onChange 函数。

function onChange(){
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("sheet2");
var sheet2lr = ss.getRange(ss.getLastRow(),1,1,2).getValues();
var sheet1lr = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("sheet1");
sheet1lr.getRange(getLastRow(),1,1,4).setValues(sheet2lr)}

我相信你的目标如下。

  • 当新行插入到“sheet2”时,您想 运行 onChange() 的脚本。
  • 您的 onChange() 函数已经安装为 OnChange 可安装触发器。

在这种情况下,我认为事件对象的changeTypesource可以用来实现你的目标。当这反映到您的脚本中时,它会变成如下。

修改后的脚本:

function onChange(e) {
  if (e.changeType != "INSERT_ROW" || e.source.getActiveSheet().getSheetName() != "sheet2") return; // Added

  // do something
  var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("sheet2"); // Or e.source.getSheetByName("sheet2");
  var sheet2lr = ss.getRange(ss.getLastRow(), 1, 1, 2).getValues();
  var sheet1lr = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("sheet1"); // Or e.source.getSheetByName("sheet1");
  sheet1lr.getRange(getLastRow(), 1, 1, 4).setValues(sheet2lr)
}
  • 在这个修改后的脚本中,当新行插入到“sheet2”时,if语句下面的脚本是运行.
  • 当你想运行这个脚本时,请在“Sheet2”的sheet中插入新行。

注:

  • 如果以上修改无效,请将OnChange触发器重新安装到函数onChange
  • 对于您的脚本,我认为您也可以使用 e.source 的事件对象而不是 SpreadsheetApp.getActiveSpreadsheet()

参考:

已添加:

关于您的以下评论,

thanks Tanaike for help me. if the user adds a row to sheet2, the onchange function works(only change equlas oparator != change ==).actually another application is adding a row to sheet2. when if i use 1 control e.source.getActiveSheet().getSheetName() == "sheet2") working but if i use second control not fire onChange e.changeType != "INSERT_ROW".

现阶段,在你的情况下,OnChange触发器可以用在手动插入行并且插入行的时候是Sheets API 而不是Google Spreadsheet 服务(SpreadsheetApp)。所以根据你的评论,在你的情况下,我认为该行是用 SpreadsheetApp 插入的。如果我的理解是正确的,我想提出以下2种模式。

模式 1:

在此模式中,您当前的 onChange() 脚本是从 actually another application is adding a row to sheet2 的函数中调用的。当你的actually another application is adding a row to sheet2脚本包含在onChange()同一个Google Apps Script项目中,假设函数名是sample(),你可以修改如下。

function sample() {
  // do something of `actually another application is adding a row to sheet2`
  
  onChange();
}

function onChange(){
  var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("sheet2");
  var sheet2lr = ss.getRange(ss.getLastRow(),1,1,2).getValues();
  var sheet1lr = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("sheet1");
  sheet1lr.getRange(getLastRow(),1,1,4).setValues(sheet2lr)
}

模式二:

在这种模式下,在您的 actually another application is adding a row to sheet2 脚本中,行插入了 Sheets API。在这种情况下,您可以使用 batchUpdate 方法的 InsertDimensionRequest 转换用于插入行的脚本。 Ref当此脚本为运行时,可以使用我建议的脚本。因为当使用 Sheets API 插入新行时,会触发 OnChange 触发器。在这种情况下,我无法理解您的 actually another application is adding a row to sheet2 脚本。至此,我只是提出了使用 Sheets API.

实现目标的方法