我如何才能 运行 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 可安装触发器。
在这种情况下,我认为事件对象的changeType
和source
可以用来实现你的目标。当这反映到您的脚本中时,它会变成如下。
修改后的脚本:
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.
实现目标的方法
我的电子表格有 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 可安装触发器。
在这种情况下,我认为事件对象的changeType
和source
可以用来实现你的目标。当这反映到您的脚本中时,它会变成如下。
修改后的脚本:
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 fireonChange 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.