Google Apps 脚本成功触发 On Form Submit,但函数不会执行

Google Apps Script successfully triggers On Form Submit, but function will not execute

如果表单响应中的值符合特定条件,我正在尝试将行从链接表单响应 sheet“主要”复制到另一个 sheet“子”,第 4 列=“子集”

我将 onFormSubmit 设置为部署 - 头部、源 - 传播sheet、事件 - 表单提交的触发器。当我提交表单时,onFormSubmit 的触发器将执行记录为已完成,但该行不会复制到“子”sheet。

getLast 函数允许我将行移动到从第二列开始的“子”sheet 中的下一个可用位置,因为我在第一列中一直有复选框 sheet.

当使用 onEdit 函数并在第 4 列中手动输入“子集”时,代码按原样工作。我似乎无法弄清楚为什么即使触发器已成功执行,onFormSubmit 也没有发生任何事情。请帮忙!

function onFormSubmit(e) {
 var ss = SpreadsheetApp.getActiveSpreadsheet();
 var s = e.source.getActiveSheet();
 var r = e.source.getActiveRange();

 if(s.getName() == "main" && r.getColumn() == 4 && r.getValue() == "Subset") {
  var row = r.getRow();
  var numColumns = s.getLastColumn();
  var targetSheet = ss.getSheetByName("sub");
  var column = targetSheet.getRange("B:B").getValues();
  var lastRow = getLast(column);
  var target = targetSheet.getRange(lastRow + 1, 2);
  s.getRange(row, 1, 1, numColumns).copyTo(target);
 }
}

function getLast(range){
 var rowNum = 0;
 var blank = false;
 for(var row = 0; row < range.length; row++){

  if(range[row][0] === "" && !blank){
   rowNum = row;
   blank = true;
  }else if(range[row][0] !== ""){
   blank = false;
  }
 }
 return rowNum;
}

我认为从你的问题来看,当你的脚本被OnSubmit触发器运行时,if(s.getName() == "main" && r.getColumn() == 4 && r.getValue() == "Subset") {}的if语句可能总是false,因为在这种情况下,范围不是列“D”。这样,您的脚本就不起作用了。我认为这可能是您遇到问题的原因。

当触发OnSubmit触发器时,为了运行if语句中的脚本,下面的修改如何?

修改后的脚本:

function onFormSubmit(e) {
  var range = e.range;
  var sheet = range.getSheet();
  var srcRange = sheet.getRange(range.rowStart, 1, 1, sheet.getLastColumn());
  if (srcRange.getValues()[0][3] == "Subset") { // srcRange.getValues()[0][3] means the column "D".
    var targetSheet = e.source.getSheetByName("sub");
    var column = targetSheet.getRange("B:B").getValues();
    var lastRow = getLast(column);
    var target = targetSheet.getRange(lastRow + 1, 2);
    srcRange.copyTo(target);
  }
}

谢谢 Tanaike,我刚在你发帖时弄明白了。表单提交触发器传递的事件对象没有 .getActiveSheet() 和 .getActiveRange() 的值,因为没有活动用户。

我的解决方案不如您的解决方案优雅,但它成功了。我很欣赏您如何通过直接从事件对象中获取 sheet 来完全绕过 SpreadsheetApp。

function onFormSubmit(e) {
   var ss = SpreadsheetApp.getActiveSpreadsheet();
   var sheet = ss.getSheetByName("main");
   var response = e.values;
  
   if(response[3] == "Subset") {
     var row = sheet.getLastRow();
     var numColumns = sheet.getLastColumn();
     var targetSheet = ss.getSheetByName("sub");
     var column = targetSheet.getRange("B:B").getValues();
     var lastRow = getLast(column);
     var target = targetSheet.getRange(lastRow + 1, 2);
     sheet.getRange(row, 1, 1, numColumns).copyTo(target);
   }
} 

经过进一步检查并受到您的解决方案的启发,我将您的方法与我在 if 语句中使用 e.values 相结合,以采用精益和实用的方法。非常感谢,田内池!

function onFormSubmit(e) {
  var response = e.range;
  
  if(response.getValues()[0][3] == "Subset") {
    var targetSheet = e.source.getSheetByName("sub");
    var col = targetSheet.getRange("B:B").getValues();
    var lastRow = getLast(col);
    var target = targetSheet.getRange(lastRow + 1, 2);
    response.copyTo(target);
  }
}