Google Sheets脚本对比SheetA与SheetB单元格后如何合并数据为单条消息发送
解决方案
核心调整思路:原有代码将邮件发送逻辑放在循环内部,每匹配到1条符合条件的数据就触发一次发送,自然会产生多封邮件。修改为先收集所有匹配记录,再统一渲染模板、单次发送邮件即可实现需求。
1. 调整Google Apps Script代码
修改后的代码如下,核心改动已标注:
function myFunction(){ var SheetA = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('SheetA'); var SheetB = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('SheetB'); // 提前提取SheetA固定参数,避免循环内重复调用接口 var StoreA = SheetA.getRange(2,2).getValue(); var Activity = SheetA.getRange(2,4).getValue(); var email = SheetA.getRange(2,5).getValue(); var lrB = SheetB.getLastRow(); // 修正原代码笔误:遍历SheetB需用SheetB的最后一行 // 初始化空数组存储所有匹配的行数据 var matchItems = []; // 遍历SheetB行收集匹配数据 for (i = 2; i <= lrB; i++){ var StoreB = SheetB.getRange(i,1).getValue(); if (StoreA == StoreB && Activity == 'Actif'){ var order = SheetB.getRange(i,2).getValue(); var date_li = SheetB.getRange(i,4).getValue(); var date = Utilities.formatDate(new Date(date_li), 'Europe/Paris', 'dd/MM/yyyy'); var ref = SheetB.getRange(i,5).getValue(); var desi = SheetB.getRange(i,6).getValue(); var quantity = SheetB.getRange(i,7).getValue(); var livred = SheetB.getRange(i,8).getValue(); // 匹配数据整理为对象存入数组 matchItems.push({ order: order, date: date, desi: desi, ref: ref, quantity: quantity, livred: livred }) } } // 仅存在匹配数据时才发送一次邮件 if(matchItems.length > 0) { const htmlTemplate = HtmlService.createTemplateFromFile('Body'); // 将整个匹配数组传给HTML模板 htmlTemplate.matchItems = matchItems; htmlTemplate.email = email; const htmlforEmail = htmlTemplate.evaluate().getContent(); console.log(htmlforEmail) MailApp.sendEmail( email, 'Modification date d\'inventaire', "SVP Ouvrez ce mail avec le support HTML", {htmlBody: htmlforEmail} ); } }
2. 修改Body.html模板
原有模板是为单条数据设计的,需要调整为遍历数组渲染多条数据,示例模板如下:
<p>Bonjour,以下是所有匹配的库存更新记录:</p> <table border="1" cellpadding="5" cellspacing="0"> <thead> <tr> <th>订单号</th> <th>日期</th> <th>参考号</th> <th>产品名称</th> <th>数量</th> <th>已交付</th> </tr> </thead> <tbody> <? for(let item of matchItems) { ?> <tr> <td><?= item.order ?></td> <td><?= item.date ?></td> <td><?= item.ref ?></td> <td><?= item.desi ?></td> <td><?= item.quantity ?></td> <td><?= item.livred ?></td> </tr> <? } ?> </tbody> </table>
优化建议
如果数据量较大,建议用getValues()批量获取整个SheetB的全部数据后再做遍历判断,比循环调用getRange()接口的效率高很多。
内容的提问来源于stack exchange,提问作者Riad
相关产品推荐
相关产品推荐

