繁体   English   中英

如何使用过滤的 forEach 循环将 (SetValues) 写入 Google 表格?

[英]How to write (SetValues) to a Google Sheet using a filtered forEach loop?

我已经尝试了几个小时以使以下 Google Apps 脚本正常工作。 它需要做的是向以下任何人发送电子邮件(来自 html 模板):

  • 有一个完整的事件时间表(如果他们被分配到至少 4 个事件,则该时间表已完成,这在 Q 列中计算);
  • 之前没有发送过 email(在 R 列中跟踪);

该脚本跟踪 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.pushmailSucces.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的这种变体

https://developers.google.com/apps-script/reference/spreadsheet/sheet#getrangerow,-column,-numrows,-numcolumns

您的数据具有不固定的行数和固定的列数 (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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM