我已经构建a spreadsheet来自动发送公式化电子邮件。它发送到客户端的电子邮件(在电子表格中定义)和CC发送需要接收所有项目的电子邮件地址。每次使用工作表时,项目/电子邮件的数量都会发生变化。
我遇到了麻烦,因为电子表格中的空白行当前会触发到CC电子邮件地址的电子邮件。我不认为我可以使用getLastRow
之类的东西来解决这个问题,因为我在某些列的每个单元格中都有公式。 如果A栏中有数据,您能帮我弄清楚如何只发送电子邮件吗?
这是我目前的剧本:
function uploadsender() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("A2:AA");
var UserData = range.getValues();
for (i in UserData) {
var row = UserData[i];
var emailaddress = row[2];
var bccaddress = row[3];
var subject = row[4];
var comments = row[5];
var filenames = row[7];
MailApp.sendEmail(emailaddress, subject, filenames + "\n\n" + comments, {
cc: "example@gmail.com",
bcc: bccaddress,
name: "John Doe"}
);
}
}
this answer似乎可能是我的解决方案:
var Avals = ss.getRange("A1:A").getValues();
var Alast = Avals.filter(String).length;
但我认为这会与我当前脚本的第3行和第4行冲突?
答案 0 :(得分:1)
您的较大问题似乎是H列中电子表格中每一行都存在公式。它们返回为某个值。
我会删除行H和单元格H1中的所有公式:
=ARRAYFORMULA(IF(ROW(A1:A)=ROW(A1),"Email Body", IF(ISBLANK(A1:A), ,J1:J&char(10)&K1:K&char(10)&L1:L) ))
分解如下: ARRAYFORMULA将把它应用于A1中的所有行(在这种情况下,因为我们使用行数组):
然后有2个嵌套的IF语句。第一个测试是否在第1行。如果是,它将Email Body放在单元格中。如果我们不这样做,那么第二个IF声明就会发挥作用。如果此行中的单元格A为空,则不执行任何操作(请注意,此处的真实区域中没有""因为实际上将值应用于单元格,与Excel不同)如果单元格A不是空白,创建文本字符串。
执行此操作,Cooper将sheet.getRange("A2:AA")
替换为sheet.getDataRange()
的原始答案完全有效,因为您应该仅使用getDataRange()为包含数据的行传递数据。
另一种选择是将所有内容包装在IF(){}中以检查A列中的值:
var row = UserData[i];
if(if(UserData[i][0] && UserData[i][0] !== 'ID'){){
var row = UserData[i];
//... Down to sending the email
}
修改强>: 显然getDataRange()甚至可以通过ARRAYFURMULA获取公式,如果它们没有返回值。所以它仍然会有太多行。所以快速搜索引导我得到getting the last row via a function的答案。这改变了代码:
function uploadsender() {
var sheet = SpreadsheetApp.getActiveSheet();
var lr = getLastPopulatedRow(sheet);
var range = sheet.getRange(2,1,lr,8);
var UserData = range.getValues();
for (i in UserData) {
if(UserData[i][0] && UserData[i][0] !== 'ID'){
//Continue to the Send Email
}
}
}
function getLastPopulatedRow(sheet) {
var data = sheet.getDataRange().getValues();
for (var i = data.length-1; i > 0; i--) {
for (var j = 0; j < data[0].length; j++) {
if (data[i][j]) return i+1;
}
}
return 0; // or 1 depending on your needs
}
如果你需要比H更多的列,则将getRange()调用中的8更改为适当的值
答案 1 :(得分:0)
而不是var range = sheet.getRange("A2:AA")
这个sheet.getDataRange()
这个循环有效,但sendMail语句似乎有问题,我不想搞砸它。
function troubleinMailVille()
{
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getDataRange();
var UserData = range.getValues();
var s='<h1>Sending Mail</h1>';
for (var i=1;i<UserData.length;i++)
{
var emailaddress = UserData[i][2];
var bccaddress = UserData[i][3];
var subject = UserData[i][4];
var comments = UserData[i][5];
var filenames = UserData[i][7];
s+= '<br />1. ' + emailaddress + ', ' + bccaddress + ', ' + subject + ', ' + comments + ', ' + filenames;
}
//MailApp.sendEmail(emailaddress, subject, filenames + "\n\n" + comments, {cc: "example@gmail.com",bcc: bccaddress,name: "John Doe"});
var html=HtmlService.createHtmlOutput(s).setWidth(800).setHeight(450);
SpreadsheetApp.getUi().showModelessDialog(html, 'Sending Emails without actually sending them');
}
答案 2 :(得分:0)
您可以使用:
sheet.getLastRow()
通过这种方式,您的脚本将获取具有值的单元格,这将减少原始脚本的执行时间。
function uploadsender() {
var sheet = SpreadsheetApp.getActiveSheet();
Get the last row with a value
var last = sheet.getLastRow()-1;
//Then you can get the range that is useful for your function
// Just replace: "var range = sheet.getRange("A2:AA");"
var UserData = sheet.getRange(2, 1, last, numColumns).getValues();
//Replace numColumns, you can use "sheet.getLastColumn();" or just writing how many columns you want to get.
for (i in UserData) {
var row = UserData[i];
var emailaddress = row[2];
var bccaddress = row[3];
var subject = row[4];
var comments = row[5];
var filenames = row[7];
MailApp.sendEmail(emailaddress, subject, filenames + "\n\n" + comments, {
cc: "example@gmail.com",
bcc: bccaddress,
name: "John Doe"
});
}
}