我遇到的问题是我写的脚本在提交表单时发送重复的电子邮件。当我打开电子表格时,脚本也会执行。我只有一个触发器设置为在提交表单时运行脚本,而且我是唯一一个对表单具有编辑权限的人。我尝试完全删除脚本项目并创建一个新项目,但没有解决问题。我不确定我的脚本是否有任何不稳定因素,但这里是:
function sendEmails() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Raw Data'); // Gets Raw Data Sheet
var lastRow = sheet.getLastRow(); // Gets last row of sheet everytime the form is submitted
var lastColumn = sheet.getLastColumn(); // Gets last column of sheet everytime the form is submitted
var value = sheet.getRange(lastRow,1,lastRow,lastColumn).getValues().toString();
var comments = sheet.getRange(lastRow, 41).getValue().toString(); // Gets additional comments from inspection form submitted
if (value.indexOf("NOT OK") > -1) {
MailApp.sendEmail({
to: "[email protected]",
subject: 'Machine Issue',
htmlBody: "An inspection of the xyz machine has returned issues: " + "<br/><br/>"
+ "<b>" + comments + "</b>" + "<br/><br/>" +
" Click " + '<a href="https:goo.gl/ahGbGu&^"> <b>HERE</b></a>'
+ " to see the last inspection report.",
});
} // Produces email based on defined parameters.
}
我也试过删除触发器并设置一个新的触发器,但也没有用。
检查执行日志。如果您有多个执行但只有一个Form Responses行,这是表单提交触发器的已知错误。解决它的唯一方法是使用脚本锁。
像这样:
SpreadsheetApp.flush();
var lock = LockService.getScriptLock();
try {
lock.waitLock(15000); // wait 15 seconds for others' use of the code section and lock to stop and then proceed
} catch (e) {
Logger.log('Could not obtain lock after 30 seconds.');
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 :("
}
START NORMAL CODE HERE
我只有一个脚本,这确实是一个问题,但这是一个非常糟糕的问题,每个表单提交最多六次执行,而scriptlock是锁定它的最整洁的方法。如果您的代码本身花费的时间少于15秒,则会缩短等待时间,以便更多的副本放弃更快。如果使用此方法,您仍会在执行日志中看到额外的副本,但它们只有15秒长。看着他们以这种方式被抓住并杀死是非常令人满意的。
这行有一个问题:
var value = sheet.getRange(lastRow,1,lastRow,lastColumn).getValues().toString();
让我们说lastRow是20.然后这个代码得到最后一行加上接下来的19行值,大概都是空白的。第三个参数是行数,第四个是列数。
最好将事件对象传递给函数并使用e.values而不必去最后一行。如果您一个接一个地提交多个表单提交,您实际上可能会收到错误的数据。
这条线也有问题:
htmlBody: "An inspection of the xyz machine has returned issues: " + "<br/><br/>"
+ "<b>" + comments + "</b>" + "<br/><br/>" +
" Click " + '<a href="https:goo.gl/ahGbGu&^"> <b>HERE</b></a>'
+ " to see the last inspection report.",
});
应删除htmlBody参数末尾的逗号。
试试这段代码:
function sendEmails(e) {
var value=e.values.toString();
var comments=e.values[40];
if (value.indexOf("NOT OK") > -1) {
var html="An inspection of the xyz machine has returned issues: ";
html+="<br/><br/>" + "<b>" + comments + "</b>" + "<br/><br/>" + " Click "
html+='<a href="https:goo.gl/ahGbGu&^"> <b>HERE</b></a>' + " to see the last inspection report.";
MailApp.sendEmail({to: "[email protected]",subject: 'Machine Issue',htmlBody: html});
//Logger.log(html);
}
}
根据@J,我多玩了一点。 G. onFormSubmit触发器返回多个触发器时出现问题。我通过使用以下用于登录onFormSubmit触发器的代码解决了测试的情况。
function testFormSubmission(ev) {
var lock=LockService.getUserLock();
try{
if(ev.values && !ev.values[1]){throw('Spurious Returns Error');}
if(lock.tryLock(10000)) {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('LogSheet');
var tA=[Utilities.formatDate(new Date(), Session.getScriptTimeZone(),"d/M/yyyy HH:mm:ss")];
tA=tA.concat(ev.values);
tA.splice(tA.length-1,1,ev.triggerUid,ev.range.rowStart,ev.range.columnEnd,JSON.stringify(ev.values));
sh.appendRow(tA);
lock.releaseLock();
}
}
catch(error){
console.error(error);
return;
}
}