【问题标题】:Trigger bug when copying rows复制行时触发错误
【发布时间】:2021-02-21 10:35:25
【问题描述】:

我有一个将行从一张纸复制到另一张纸的功能,当我手动运行它时它可以工作:

function updateDataRange() {
  var formSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Form Responses 1");
  var lastFormRow = formSheet.getLastRow();
  var dataSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DataRange");
  dataSheet.clear();
  for(var rowCounter = 1; rowCounter <= lastFormRow; rowCounter++) {
    var sourceRange = formSheet.getRange('B'+rowCounter+':H'+rowCounter);
    var insertRow = dataSheet.getLastRow() + 1;
    var targetRange = dataSheet.getRange('A'+insertRow);
    sourceRange.copyTo(targetRange);
  }
}

但是,当我通过触发器(例如 function onEdit(e) { updateDateRange(); } )运行它时,行中会出现间隙,并且某些值将被遗漏。在这种情况下,我知道通过使用rowCounter 而不是insertRow 来写入文件而不是使用getLastRow() 来“修复”,但是人们可以很容易地看到在另一种情况下这是一个问题。

所以我想我的问题很简单:为什么在使用触发器时不能正常工作?

编辑:为了澄清,我有第三张表,其中包含一些条件/单元格(即影响要复制哪些行的条件)并更改它们(例如更改不同的日期)会触发该功能.

【问题讨论】:

    标签: google-apps-script google-sheets


    【解决方案1】:

    解释:

    您正在使用onEdit 触发器来捕获工作表更改。但onEdit 触发器仅在 用户 更改单元格的值时起作用。引用official documentation

    onEdit(e) 触发器会在 用户 更改值时自动运行 电子表格中的任何单元格。

    在您的情况下,我认为您正在尝试在Form Responses 工作表中填写表单数据时执行此代码。

    有两种触发函数可以处理表单提交,它们都是installable

    一个是google sheet event based trigger,另一个是form event based trigger

    您的目标是从 google 表格端执行一些代码,因此使用第一个是有意义的。

    修改:

    1. 将函数名称从 onEdit 更改为您选择的其他名称,例如myFormSubmitTrigger.

    2. 由于触发器是可安装的,您需要为myFormSubmitTrigger 函数“安装”onFormSubmit 触发器。 Here 你可以找到一些简单的操作说明。

    【讨论】:

    • 感谢您的回复!但是,我确实希望(并且确实)希望在更改单元格中的值时触发此操作(更具体地说,更改确定要复制哪些单元格的单元格)。并且代码应该以任何一种方式工作,不是吗?
    • @Markstar 问题是谁来改变单元格的值?一个公式?脚本?填好的表格?用户?
    • 用户。我有一张带有条件的工作表,计划是每当更改一个条件时,都会触发该功能。
    【解决方案2】:

    如果您的问题是为什么当表单对表单响应 1 进行更改时您的功能不起作用,那么 Marios 已经回答了您的问题,接受它并继续前进。如果您在用户使用简单触发器对表单响应 1 进行编辑时尝试运行您的函数,那么对于没有完全复制所有行的可能解释是简单触发器必须在 30 秒内完成。如果您继续在 Form 1 Responses 中接受更多数据,那么迟早您会遇到问题,但是使用此功能会晚很多,因为它的运行速度会比您的代码快得多:

    function updateDataRange() {
      const sss=SpreadsheetApp.openById('ssid');
      const ssh=e.source.getSheetByName('Form Responses 1');
      const sr=2;
      const svs=ssh.getRange(sr,2,sh.getLastRow()-ssr+1,7).getValues();
      const dsh=e.source.getSheetByName('DataRange');
      dsh.clear();
      dsh.getRange(1,1,svs.length,svs[0].length).setValues(svs);
    }
    

    但是,我建议您永远不要编辑表单回复表。我会考虑使用 onFormSubmit 触发器将所有数据捕获到可编辑的第二张工作表中。它将通过dsh.appendRow(e.values) 自动附加额外的数据。因此,现在您将不再需要 onEdit 触发器,因为您的数据表通过 onFormSubmit 触发器保持最新数据,您可以随时随意编辑数据表。

    如果这些问题都不够,那么我建议您更清楚地了解您的要求。

    【讨论】:

    • 该函数确实执行了 - 它只是有问题,即某些行被跳过,一些行被复制多次。在我的测试文件中,脚本大约需要 5 秒。此外,触发器来自另一张表,因此不应影响数据。我将编辑上面的帖子以使其更清晰。
    • 请说得更清楚,请清楚您正在使用什么触发器,正在编辑什么以及预期的输出是什么。我们应该能够为您提供代码并重现相同的问题。阅读minimal reproducible example
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-17
    • 2017-09-13
    相关资源
    最近更新 更多