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);
}
}
如果表单响应中的值符合特定条件,我正在尝试将行从链接表单响应 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);
}
}