【问题标题】:Google script - send email alertGoogle 脚本 - 发送电子邮件提醒
【发布时间】:2021-09-07 19:39:29
【问题描述】:

我有一个脚本可以查看 G 列中的值,如果 A 列中的对应单元格为空,则给我发送一封电子邮件。

--- 工作原理--

  • 它适用于静态值:它为 G 列中的每个非空单元格发送一封电子邮件,而 A 列中没有任何值

--- 什么不起作用--

  • 当从另一个选项卡中获取 A 列值时,它会发送几封电子邮件,我认为它是每个 G 列单元格(无论是否为空)。这样一来,所有 G 和 A 单元格都有数据,所以我收到了多封不需要的电子邮件。

这是脚本代码:

  const ss = SpreadsheetApp.getActive();
  const sh = ss.getSheetByName('Sheet to send emails');
  const data = sh.getRange('A2:G'+sh.getLastRow()).getValues();
  data.forEach(r=>{
     let overdueValue = r[0];  
     if (overdueValue === ""){
         let name = r[6];
         let message = 'Text ' + name;
         let subject = 'TEXT.'
         MailApp.sendEmail('myemail@gmail.com', subject, message); 
     }
  });  
}

这是测试表的链接:

https://docs.google.com/spreadsheets/d/1OKQlm0PjEjDB7PXvt34Og2fa4vPZWnvLazTEawEtOXg/edit?usp=sharing

在这个测试用例中,我“应该”只收到一封与 ID 55555 相关的电子邮件。使用原样的脚本,我收到一封与 55555 相关的邮件,而其他几个“未定义”。

为避免电子邮件垃圾邮件,我没有将脚本添加到该工作表,但它显示了“Vlookup”的想法。

谁能帮帮我,好吗? 提前谢谢你

【问题讨论】:

    标签: email google-apps-script


    【解决方案1】:

    问题:

    您的原始脚本的问题是 sh.getLastRow 返回 1000(它还处理那些没有内容的行,结果未定义)

    修复 1:获取 G 列的特定最后一行:

    const gValues = sh.getRange('G1:G').getValues();
    const gLastRow = gValues.filter(String).length;
    

    修复 2:过滤数据

    const data = sh.getRange('A2:G' + sh.getLastRow()).getValues().filter(r => r[6]);
    

    注意:

    • 正如 Kris 在 cmets 中提到的,在特定情况下获取上面的最后一行将失败(与 getNextDataCell 相同)。当列的第一行和最后一行之间有空白行时,这将无法正确获取最后一行。如果您有这种数据,请使用第二种过滤数据的方法。
    • 如果 G 列中的数据在第一行和最后一行之间没有空白单元格,那么任何方法都应该有效。

    【讨论】:

    • 很好的答案,这种方法的一个潜在缺陷 - 如果数据集中 G 列中有空白单元格,则过滤器/长度数将小于 G 列中数据的最后一行。
    • @Kris,感谢您的关注。不同的方法实际上会发布不同的问题。 getNextDataCell 有同样的问题。它只会得到中间没有空白单元格的最后一行。在循环之前过滤数据可能是最好的情况,但如果中间没有空白列 G 数据,那么上面列出的任何方法都应该有效。
    • 我从惨痛的教训中吸取了教训。一列中有两个空单元格,有 300 行数据。让我发疯,试图弄清楚为什么它会覆盖最后几行。
    • 在答案底部添加注释供 OP 查看。谢谢@Kris。
    • 感谢您的帮助和详细解释!这种情况很少见,但可能会发生我在填充的单元格之间确实有空单元格,但我会测试您建议的选项并留下我的输入。与此同时,我只是不想让你认为我忽略了你的帮助:)
    【解决方案2】:

    我检查了你的测试表,sh.getLastRow() 是 1000。

    选项 1

    如果 G 列在填充的单元格之间没有空单元格,那么您可以这样做:

      const ss = SpreadsheetApp.getActive();
      const sheet = ss.getSheetByName("Sheet to send emails");
      
      // get the first cell in column G
      var gHeader = sheet.getRange(1, 7);
    
      // equivelent of using CTRL + down arrow to find the last da
      var lastRow = gcell.getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow();
    
      const data = sheet.getRange(2, 1, lastRow, 7).getValues();
    

    选项 2

    在您的代码中添加另一个条件 - 像这样:

      data.forEach(r=>{
         let overdueValue = r[0]; 
         let name = r[6] 
         
         // check if the value in col A is blankd and col G is not blank
         if (overdueValue === "" && name !== ""){
             let message = 'Text ' + name;
             let subject = 'TEXT.'
             MailApp.sendEmail('myemail@gmail.com', subject, message); 
         }
      });
    

    为了加快速度,使用命名范围来限制它必须迭代的行数:

      const ss = SpreadsheetApp.getActive();
      const data = ss.getRangeByName("Your_NamedRange_Here").getValues();
    

    【讨论】:

    • 感谢您的帮助。我已经尝试过选项 2 并且它有效。这样一个“简单”的添加...... :)
    猜你喜欢
    • 1970-01-01
    • 2018-12-09
    • 2022-11-16
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-27
    • 2011-09-16
    相关资源
    最近更新 更多