如何用App Script合并相同数据行并去重?解决邮件合并重复问题
优化Google Apps Script行合并代码以避免重复数据
问题背景
需要实现邮件合并功能:将第一列数据相同的多行记录合并为一行,用于后续发送统一邮件。现有代码仅通过第一列判断合并,但合并单元格时直接累加内容,导致出现重复数据,需优化实现无重复的合并效果。
原代码核心问题
原代码在合并同组行的非第一列内容时,未做重复检查,直接将后续行的内容追加拼接,比如同一分组下多行有相同的内容时,合并后会重复出现。
优化后的代码
function mergeRowsWithoutDuplicates() { const sht = SpreadsheetApp.getActiveSheet(); const firstRow = 2; // 数据起始行(跳过表头) const dataRange = sht.getRange(firstRow, 1, sht.getLastRow() - firstRow + 1, sht.getLastColumn()); const data = dataRange.getValues(); // 先按第一列排序,确保相同分组的行连续 data.sort((a, b) => a[0].toString().localeCompare(b[0].toString())); // 用对象分组:键为第一列值,值存储各列的去重集合和最后一列的总和 const groupedData = {}; data.forEach(row => { const key = row[0]; if (!groupedData[key]) { // 初始化分组:第一列直接存值,其他列用Set去重,最后一列初始化总和 groupedData[key] = { cols: row.slice(0, -1).map((val, idx) => idx === 0 ? val : new Set([val])), total: Number(row[row.length - 1] || 0) }; } else { // 合并当前行到分组中 row.slice(0, -1).forEach((val, idx) => { if (idx !== 0 && val) { // 第一列不用处理,其他列添加到Set去重 groupedData[key].cols[idx].add(val); } }); // 累加最后一列数值 groupedData[key].total += Number(row[row.length - 1] || 0); } }); // 转换为输出数组:将Set转为逗号分隔的字符串,拼接总和 const output = Object.values(groupedData).map(group => { const mergedCols = group.cols.map(col => { return col instanceof Set ? Array.from(col).join(', ') : col; }); mergedCols.push(group.total); return mergedCols; }); // 清空原数据区域并写入合并后的数据 dataRange.clearContent().setWrap(true); if (output.length > 0) { sht.getRange(firstRow, 1, output.length, output[0].length).setValues(output); } // 设置列宽 const colWidth = 250; sht.setColumnWidth(2, colWidth); sht.setColumnWidth(3, colWidth); sht.setColumnWidth(4, colWidth); }
代码说明
- 分组与去重逻辑:使用
Set存储每一列的内容,自动实现去重,避免重复值出现在合并后的单元格中 - 数值累加:最后一列单独处理,直接累加数值,保持原有的求和逻辑
- 排序处理:先对第一列排序,确保相同分组的行连续,保证分组逻辑正确
- 高效数据处理:通过对象分组的方式替代原有的循环判断,代码逻辑更清晰,执行效率更高
内容的提问来源于stack exchange,提问作者Supadech Wangnaitham
相关产品推荐
相关产品推荐

