首页 > 解决方案 > 用于表格的 Google App 脚本 - 从编辑器运行时 forEach 有效,但从时间触发器运行时没有数据

问题描述

我有一个在 App 脚本中发送电子邮件并使用 HTML 模板构建电子邮件正文的函数。forEach 循环遍历工作表中的行。

当我从编辑器运行我的函数时,一切正常。电子邮件正文包含我希望看到的行。没有错误。

当时间驱动的触发器运行它时,电子邮件中的输出缺少我的 forEach 循环中的数据(tr 和 td),该循环位于 .html 文件/模板中。

当我查看执行日志(时间驱动触发器)时,没有错误,并且日志与电子邮件正文一致。

在测试时,我将触发计时器设置为“每 1 分钟”。

这是code.gs:

function sendScheduledEmailRFP() {
  Logger.log("function executed");
  /* Connect to spreadsheet */
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const ws = ss.getSheetByName("Data");
  var values = ss.getDataRange().getDisplayValues();
  const htmlTemplateRFP = HtmlService.createTemplateFromFile("rfpEmail");
  htmlTemplateRFP.values = values;
  const htmlForRfpEmail = htmlTemplateRFP.evaluate().getContent();

  MailApp.sendEmail(
    "email@address.com",
    "subject", 
    "Blabla", 
    { 
      htmlBody: htmlForRfpEmail
    }
  );
  Logger.log(htmlForRfpEmail);
}

这是 .html 代码(仅 forEach 部分):

  <tbody>
    <? values.forEach(r => { 

      if(r[2] === "RFP" && r[9] !== "On hold"){ ?>
        <tr>
          <td style="border: 1px solid black; text-align: left; padding: 5px; font-size: 10px;">
            <?= r[5] ?>
          </td>
          <td style="border: 1px solid black; text-align: right; padding: 5px; font-size: 10px;">
            <?= r[13] ?>
          </td>
          <td style="border: 1px solid black; text-align: right; padding: 5px; font-size: 10px;">
            <?= r[27] ?>
          </td>
        </tr>
   <? 
      } 
    }) 
   ?>
  </tbody>

这是从时间驱动触发器执行时函数的日志输出:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body style="font-family: Arial, Helvetica, sans-serif;">
   <div>
     <div>
       <h3>Today's list</h3>
       <table style="border-collapse: collapse; border: 1px solid black; font-family: Arial, Helvetica, sans-serif; width: 300px;">
         <thead>
           <tr style="background-color: #ffd166;">
             <th colspan="3" style="border: 1px solid black; text-align: left; padding: 5px; font-size: 12px;">
               Today's list
             </th>
           </tr>
         </thead>
       <tbody>
       </tbody>
     </table>  
   </div>      
 </div>

我已经尝试删除触发器并重新创建一个......同样的问题。请帮忙!

标签: htmlemailgoogle-apps-scriptgoogle-sheets

解决方案


在工作表上使用getDataRange(),而不是在电子表格上使用

  • 如果不指定工作表,getDataRange()则默认检索活动工作表上的数据范围

  • 在时间驱动触发器上运行函数时,活动工作表始终默认为电子表格的第一个工作表。

  • 如果要在工作表上检索数据范围,则Data需要修改代码如下:

  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const ws = ss.getSheetByName("Data");
  var values = ss.getDataRange().getDisplayValues();

  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const ws = ss.getSheetByName("Data");
  var values = ws.getDataRange().getDisplayValues();

边注:

对于故障排除,在代码中的战略位置实现日志总是有帮助的。例如values,在检索到它们后记录,记录r[2]r[9].


推荐阅读