【问题标题】:Script running multiple times onFormSubmit脚本在FormSubmit 上运行多次
【发布时间】:2019-03-21 15:11:11
【问题描述】:

我将以下代码设置为基于 onFormSubmit 触发器运行,但有时它会在同一次提交时运行多次。我想验证它是否已经复制了该行,如果是,则停止脚本。

function toDo(){
  var responses = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Form Responses 1");
  var jobs = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Jobs");
  var lastrow = responses.getLastRow();
  var col = responses.getLastColumn();
  var row = responses.getRange(lastrow, 1, 1, 19).getValues();

  jobs.appendRow(row[0]);
  //copyValuesOnly(copyFromRange, copyToRangeStart);

  var si = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Jobs');

  var range = si.getRange("A2:R");

  range.sort({column: 5,ascending: true}),({column: 1, ascending:true});

}

【问题讨论】:

  • 有必要吗?我的意思是,在 Google 中,当您提交表单时,响应会自动发送到 Google 电子表格。
  • 所以我将它设置为复制到一个新工作表,然后可以在工作完成后删除它们,所以我们只查看需要完成的工作,同时维护所有列表工作。
  • 看看this
  • 所以我对如何将其添加到代码中感到困惑,我不确定 e.values 是什么我知道我的工作表中的 k 列与冗余部分完全相同原始运行。

标签: google-apps-script google-sheets google-forms


【解决方案1】:

这是 GAS + Forms 的一个已知问题。解决它的方法是创建一个脚本锁,拒绝(导致它们提前返回)一段时间内的所有其他尝试。

function toDo(){
     SpreadsheetApp.flush();
     var lock = LockService.getScriptLock();
  try {
    lock.waitLock(5000); 
     } catch (e) {
        Logger.log('Could not obtain lock after 5seconds.');
        return HtmlService.createHtmlOutput("<b> Server Busy please try after some time <p>")
        // In case this a server side code called asynchronously you return a error code and display the appropriate message on the client side
        return "Error: Server busy try again later... Sorry :("
     }
  var responses = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Form Responses 1");
  var jobs = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Jobs");
  var lastrow = responses.getLastRow();
  var col = responses.getLastColumn();
  var row = responses.getRange(lastrow, 1, 1, 19).getValues();

  jobs.appendRow(row[0]);
  //copyValuesOnly(copyFromRange, copyToRangeStart);

  var si = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Jobs');

  var range = si.getRange("A2:R");

  range.sort({column: 5,ascending: true}),({column: 1, ascending:true});
  Utilities.sleep(5000);
  lock.releaseLock)();
}

我有脚本执行此操作多达 8 次,通常每 2-3 秒执行一次。使用此解决方案,您将在开始时锁定,然后在结束时休眠,以确保进程时间大于等待时间。 (这里我用了 5 秒,这应该可以防止重复输入)。

【讨论】:

  • 这是否会阻止合法的表单提交运行,例如多个用户同时或接近同时输入,或者一个用户提交多个类似的表单条目?
  • 在接下来的五秒内是的。有一些解决方法涉及到 keeper 功能定期检查未处理的项目,但我只是偶尔使用它们。
【解决方案2】:

我注意到,如果您只是使用脚本制作另一个工作表副本,此错误就会消失。似乎重置了原始副本中的任何问题。还可以尝试禁用谷歌表单上的回复回执。

【讨论】:

    【解决方案3】:

    我注意到如果我重命名 onFormSubmit 调用的函数并保存脚本,问题就解决了。

    如果我在脚本编辑器中单击“运行”,每次提交表单都会收到 2 封电子邮件。如果我再次单击“运行”,每次提交表单都会收到 3 封电子邮件。如果我再次更改函数名称,我将重置为每个表单提交仅 1 封电子邮件。

    不知何故,当我运行脚本时,它会复制触发器。

    【讨论】:

      猜你喜欢
      • 2016-03-26
      • 1970-01-01
      • 2012-06-27
      • 2021-08-24
      • 2016-08-25
      • 2017-01-07
      • 2013-11-25
      • 1970-01-01
      • 2020-02-14
      相关资源
      最近更新 更多