【问题标题】:OnChange Trigger that will fire when there's an update on a specified column指定列有更新时触发的 OnChange 触发器
【发布时间】:2020-09-08 04:22:22
【问题描述】:

我有 2 个电子表格,即 SourceDestination。在 Source 中,我列出了我的示例产品及其指定价格,并使用 IMPORTRANGE 功能复制到 Destination。现在,我正在尝试仅在 'Destination Sheet 1'B:B 上有更新时触发 OnChange 触发器。这是我的代码:

function testFunction(e) {
  var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Destination Sheet 1");
  if (e.source.getSheetName = "Destination Sheet 1" && e.range.getRow() > 1 && e.range.getColumn() == 2){
    var range = ss.getRange(e.range.getRow(), 3, ss.getLastRow());
    range.setValue("There's an update");
  }
}

我还添加了函数testFunction on OnChange Trigger.

但是,基于Event Objects Documentation,我无法获取从事件对象更新的范围。 “范围”是指目标表 1'B:B。我收到此错误:

“TypeError:无法读取 testFunction 处未定义的属性 'getRow'(代码:3:64)”

期望的结果(在更新'Destination Sheet 1'中的定价之后!B:B):

我对谷歌脚本还是很陌生,我真的尝试了我能想到的所有东西,但它并没有让我有任何收获。任何帮助是极大的赞赏。提前谢谢!

更新 1: 当 IMPORTRANGE 函数的工作表上有更新时,似乎无法触发 OnChange 触发器。

替代方案: 由于它不起作用,我正在考虑在 Source 上使用 OnEdit 触发器来处理该编辑并将我想要的结果应用于 Destination。但是,我遇到了权限问题。

例外:您无权调用 SpreadsheetApp.openById。所需权限:https://www.googleapis.com/auth/spreadsheets

这是我的代码:

function onEdit(e){
  aSourceFunction(e);
}

function aSourceFunction(e) {
  //IF stmt to make sure that OnEdit Trigger is not triggerred anywhere
  if (e.source.getSheetName = "Source Sheet 1" && e.range.getRow() > 1 && e.range.getColumn() == 2){

    //my attempt to call Destination Sheet 1 from Destination 
    var ss = SpreadsheetApp
    .openByID("1QMtU6VbNQyDLXMHmaLBBDePH5l")
    .setActiveSheet("Destination Sheet 1");
    
    //desired outcome
    ss.getRange(e.range.getRow(), 4, ss.getLastRow()).setValue("There's an update");
  }
}

另外,我不确定我的担忧是否相关,但我在某处读到我的代码不应该有 @OnlyCurrentDoc 但我的代码中没有任何地方,即使在我的清单文件中也是如此。

{
  "timeZone": "Asia/Hong_Kong",
  "dependencies": {
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8"
}

这是它的范围:

更新 2: 成功了!最初,我有一个简单的 OnEdit 触发器。但是,根据this,您需要有一个可安装的 OnEdit 触发器才能工作(还修复了我的错误代码),当我运行代码时,“权限提示”出现让我访问目标电子表格.这是我的代码,供任何需要的人使用:

function aSourceFunction(e) {
  //IF stmt to make sure that OnEdit Trigger is not triggerred anywhere
  if (e.source.getSheetName = "Source Sheet 1" && e.range.getRow() > 1 && e.range.getColumn() == 2){

    
    //my attempt to call Destination Sheet 1 from Destination 
    var ss = SpreadsheetApp.openById("1QMtU6VbNQyDLXMHmaLBBDePH5l-4wDPUNQ827gb3jXY");
    var sheet = ss.getSheetByName("Destination Sheet 1");
    
    
    //desired outcome
    sheet.getRange(e.range.getRow(), 4).setValue("There's an update");
  }
}

注意:转到编辑>当前项目的触发器>添加触发器,使用 aSourceFunction 作为您的函数并使用 OnEdit 作为触发器。

【问题讨论】:

  • 源表中的 B:B 如何变化?
  • @TheMaster 我正在手动更改值。我正在考虑使用 OnEdit,因为它会在您手动执行时自动触发,但我需要触发 OnChange。
  • 为什么需要onChange?
  • 不要用答案/解决方法编辑您的问题。请在下方添加答案。
  • 当 IMPORTRANGE 函数的工作表上有更新时,似乎无法触发 OnChange 触发器。 错误。您可以触发它,但它不会告诉您更改了哪个范围

标签: javascript google-apps-script google-sheets triggers


【解决方案1】:

来自问题

但是,基于Event Objects Documentation,我无法获取从事件对象更新的范围。 “范围”是指目标表 1'B:B。

你是对的,没有办法从更改事件对象中获取更新的范围。

但如果您已经知道感兴趣的范围是'Destination Sheet 1'!B:B,您可以使用:

var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var range = spreadsheet.getRange("Destination Sheet 1!B:B");

关于它发生的错误消息,因为更改事件对象不包含range 属性。

请记住(来自Installable Triggers

当用户修改电子表格本身的结构时(例如,通过添加新工作表或删除列)运行可安装的更改触发器。

关于如何使 OnChange 触发器仅在 B 列更新时触发,您可以尝试使用 getActiveRange(),但有时它不起作用。有一个与此getActiveRange() incorrect in onChange trigger for some column/row operations相关的未解决问题

相关

【讨论】:

  • 感谢您的回答!真的很感激!但是有一个问题,我怎样才能使 OnChange 触发器仅在 B 列的更新时触发?
  • 您可以尝试使用getActiveRange(),但有时它不起作用。有一个与此 getActiveRange() incorrect in onChange trigger for some column/row operations 相关的未解决问题
  • @Rubén 已经检查过了。不适用于 importrange。
  • 感谢两位花时间回答我的问题。如果这不起作用,我正在考虑的替代方法是使用 Source 中的 OnEdit 触发器处理手动编辑。但是,由于权限问题,我似乎无法这样做。我会更新我的帖子,以便您检查。再次感谢你。 :)
猜你喜欢
  • 2017-10-09
  • 1970-01-01
  • 2019-09-08
  • 2017-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-08
相关资源
最近更新 更多