我正在遇到一个问题,我编写的脚本在提交表格时发送了重复的电子邮件。当我简单地打开电子表格时,脚本也有时会执行。在提交表单时,我只设置了一个触发器来运行脚本,而我是唯一一个可以编辑访问该表的脚本。我尝试完全删除脚本项目并创建一个没有解决问题的新项目。我不确定我的脚本是否有任何奇怪的东西,但是这里是:
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: "test@test.com",
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.
}
我还尝试删除触发器并设置一个新的触发器。
检查您的执行日志。如果您有多个执行,但只有一个表单响应行,这是表单提交触发器的已知错误。解决它的唯一方法是使用脚本锁。
这样:
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: "test@test.com",subject: 'Machine Issue',htmlBody: html});
//Logger.log(html);
}
}
- 表格提交事件对象
我和@J一起玩了更多。G. OnFormSubmit触发器返回多个触发器存在问题。我通过使用以下代码来登录FormSubmit触发器的测试情况。
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;
}
}