[英]How to write (SetValues) to a Google Sheet using a filtered forEach loop?
我已经尝试了几个小时以使以下 Google Apps 脚本正常工作。 它需要做的是向以下任何人发送电子邮件(来自 html 模板):
该脚本跟踪 S 列中的错误,即是否没有提供 email 地址。
看来它只有效:
如果我注释掉
data = data.filter(function(r){ return r[17] == true & r[16] > 3});
或者如果我注释掉
ws.getRange("S3:S" + ws.getLastRow()).setValues(errors); ws.getRange("R3:R" + ws.getLastRow()).setValues(mailSucces);
我怎样才能让这个脚本正常工作? 我指的谷歌表格的副本是这个: https://docs.google.com/spreadsheets/d/1sbOlvLVVfiQMWxNZmtCLuizci2cQB9Kfd8tYz64gjP0/edit?usp=sharing
到目前为止,这是我的代码:
function SendEmail(){
var voornaam = 3;
var achternaam = 4;
var email = 5;
var event1 = 9;
var event2 = 10;
var event3 = 11;
var event4 = 12;
var event5 = 13;
var event6 = 14;
var event7 = 15;
var emailTemp = HtmlService.createTemplateFromFile("email");
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Events Day 1");
var datum = ws.getRange(1,3).getValue();
var spreker = ws.getRange(1,6).getValue();
var data = ws.getRange("A3:R" + ws.getLastRow()).getValues();
data = data.filter(function(r){ return r[17] == false && r[16] > 3}); //Either this needs to be commented out...
let errors = [];
let mailSucces = [];
data.forEach(function(row){
try{
emailTemp.voornaam = row[voornaam];
emailTemp.email = row[email];
emailTemp.datum = datum;
emailTemp.spreker = spreker;
emailTemp.event1 = row[event1];
emailTemp.event2 = row[event2];
emailTemp.event3 = row[event3];
emailTemp.event4 = row[event4];
emailTemp.event5 = row[event5];
emailTemp.event6 = row[event6];
emailTemp.event7 = row[event7];
var htmlMessage = emailTemp.evaluate().getContent();
GmailApp.sendEmail(
row[email],
"Here you go! Your personal schedule for the event of " + datum,
"Your emailprogramm doesn't support html.",
{
name: "Event Organisation Team", htmlBody: htmlMessage, replyTo: "info@fakeemail.com"
});
errors.push([""]);
mailSucces.push(["TRUE"]);
}
catch(err){
errors.push(["Error: no message sent."]);
mailSucces.push(["False"]);
}
}); //close forEach
ws.getRange("S3:S" + ws.getLastRow()).setValues(errors); //or this and the next line need to be commented out.
ws.getRange("R3:R" + ws.getLastRow()).setValues(mailSucces);
}
编辑我一直在尝试和思考......但仍然没有找到如何让它发挥作用。 但我也理解了为什么它不起作用; 我只是不知道如何修复它。 让我再详细说明一下这个问题:问题是,在forEach
循环中,范围是数据的过滤变体,使用getValues
从电子表格中提取。 因此,使用ws.getRange("R3:R" + ws.getLastRow()).setValues(mailSucces);
写回数据导致电子表格中的复选标记不匹配。 所以,不知何故我需要把以前使用的过滤器的范围data = data.filter(function(r){ return r[17] == false & r[16] > 3});
在变量中...? 我猜?
此外,我认为在循环中使用setValue
并不明智,因为(根据我从对该主题的搜索中了解到)这会导致脚本变慢,因为脚本的每个循环都会调用 API 来写入电子表格. 因此, errors.push
和mailSucces.push
以及我在循环结束后尝试在最后做一个 setValue 的尝试。
有人可以帮我完成这个问题吗?
问题是您写入的范围和您正在写入的数据的大小不同。
尝试更换:
ws.getRange("S3:S" + ws.getLastRow()).setValues(errors);
ws.getRange("R3:R" + ws.getLastRow()).setValues(mailSucces);
和:
ws.getRange(3, 19, errors.length, 1).setValues(errors);
ws.getRange(3, 18, mailSucces.length, 1).setValues(mailSucces);
您应该使用getRange的这种变体
您的数据具有不固定的行数和固定的列数 (1)。 在一般情况下,您的数据将是 X 行和 Y 列的矩阵。 为此,您可以使其完全动态:
sheet.getRange(startRow, startColumn, data.length, data[0].length)
在执行此操作之前,请确保 data.length > 0,否则 data[0].length 会中断。
编辑:我开始写评论,但太长了。 有几件事可能 go 发送电子邮件出错。 我注意到的第一件事是您在过滤器中使用& ,但在 AppsScript/JavaScript/C-like-languages 中,您应该使用&&进行逻辑与。 现在是 email:您只能使用 catch 块检测代码中断。 在这一点上,你不知道为什么代码会破坏它可能是任何东西。 使用 GmailApp,我建议您在开发时使用 createDraft,然后在一切正常后将其替换为 sendEmail 以获得最终版本,这两个函数具有完全相同的参数,谢谢 Google 开发人员;-)。
要找出确切的问题,您应该在中断时收到错误消息并显示它。 err.stack应该告诉你几乎所有的东西:
catch(err){
Logger.log(err.stack); // Added
errors.push(["Error: no message sent."]);
mailSucces.push(["False"]);
}
从代码编辑器运行sendEmail function,您应该会看到每个 catch(err) 传递的日志。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.