使用Google Apps Script统计列重复值:自定义countIf脚本故障求助
修复自定义CountIf脚本实现员工姓名次数统计
原脚本的核心问题
- 内层循环错误递增
i而非j,直接破坏循环逻辑,导致无法正常遍历数据 - 循环内重复调用
getRange()获取数据,不仅低效率,还会触发Google Apps Script的API调用限制 - 写入结果时
getRange('John Smith', 'Jane Doe' + (i+1).toString())参数完全错误,getRange()的行/列参数需为数字,不能直接用姓名字符串 - 统计逻辑混乱,没有实现“按姓名去重统计次数”的核心需求
修正后的实现代码
以下脚本会统计Source表B列(从B27开始)的员工姓名出现次数,将结果写入同表的D列(姓名)和E列(次数):
function countEmployeeOccurrences() { // 获取当前活跃表格(避免硬编码ID,更灵活) const ss = SpreadsheetApp.getActiveSpreadsheet(); const sourceSheet = ss.getSheetByName("Source"); // 获取B27到最后一行的数据,转为一维数组方便处理 const nameRange = sourceSheet.getRange("B27:B" + sourceSheet.getLastRow()); const names = nameRange.getValues().flat().filter(name => name !== ""); // 过滤空值 // 用对象统计每个姓名的出现次数 const countMap = {}; names.forEach(name => { countMap[name] = (countMap[name] || 0) + 1; }); // 将统计结果转为二维数组,准备写入表格 const result = Object.entries(countMap); // 清空之前的统计结果(D27开始的区域),避免残留旧数据 const clearRange = sourceSheet.getRange("D27:E" + sourceSheet.getLastRow()); clearRange.clearContent(); // 写入新的统计结果到D27开始的位置 if (result.length > 0) { sourceSheet.getRange(27, 4, result.length, 2).setValues(result); } }
使用说明
- 可以将这个函数和你的
appendRows函数绑定到同一个自定义菜单,这样每次更新数据源后,一键触发两个操作 - 如果需要自动触发,可以在
appendRows函数末尾直接调用countEmployeeOccurrences(),实现更新后自动统计;也可设置时间驱动触发器定期执行 - 若要调整统计列或结果写入位置,修改代码中的
B27:B、D27:E等范围参数即可
关键优化点
- 一次性获取所有数据,减少Google Apps Script的API调用次数(这是提升脚本性能的核心)
- 使用对象统计次数,逻辑清晰且效率高
- 过滤空值,避免统计无效数据
- 写入前清空旧结果,保证数据准确性
内容的提问来源于stack exchange,提问作者Tiarnie Hillman
相关产品推荐
相关产品推荐

