Google Sheets移除含原条目的重复数据问题及脚本优化需求
移除Google Sheets中C列重复的所有条目(含原始行)
我需要在Google Sheets里移除C列存在重复值的所有行,包括原始条目。一开始用了这段代码,能正常运行但只保留唯一值,没法满足“删除所有重复行(含原始)”的需求:
function removeDuplicate2ndPhase() { var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Hourly Data'); var lastRow = sheet.getLastRow(); var range = sheet.getRange('B3:M' + lastRow); range.removeDuplicates([3]); }
之后我试了keepUniqueValues函数,虽然能实现目标,但有个问题:如果手动修改某行的C列值,哪怕其他行数据完全一致,该行还是会被删掉,这不是我想要的效果:
function keepUniqueValues() { var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Hourly Data'); var lastRow = sheet.getLastRow(); var range = sheet.getRange('B3:M' + lastRow); // 获取指定区域的所有值 var values = range.getValues(); var uniqueCheck = {}; var uniqueValues = []; // 遍历区域内的每一行 for (var i = 0; i < values.length; i++) { var row = values[i]; var key = row[2]; // 假设第三列(索引2)是要检查重复的列 // 检查key是否已在uniqueCheck中 if (!uniqueCheck[key]) { uniqueCheck[key] = true; uniqueValues.push(row); } else { // 如果key已存在,从uniqueValues中移除对应的行(如果存在) var indexToRemove = uniqueValues.findIndex(function(existingRow) { return existingRow[2] === key; // 检查已有行是否有相同的key值 }); if (indexToRemove !== -1) { uniqueValues.splice(indexToRemove, 1); } } } // 清空区域内的现有数据 range.clearContent(); // 将唯一值写回区域 if (uniqueValues.length > 0) { range.offset(0, 0, uniqueValues.length, uniqueValues[0].length).setValues(uniqueValues); } }
修正方案
原代码的问题在于用布尔值标记值是否出现过,没有统计出现次数——如果修改后某个C列值变成唯一的,原逻辑会错误地把它移除。正确的做法是先统计每个C列值的出现次数,再筛选出仅出现一次的行:
function removeAllDuplicateRows() { const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Hourly Data'); const lastRow = sheet.getLastRow(); const range = sheet.getRange('B3:M' + lastRow); const values = range.getValues(); // 统计C列(索引2)每个值的出现次数 const countMap = {}; values.forEach(row => { const key = row[2]; countMap[key] = (countMap[key] || 0) + 1; }); // 仅保留C列值出现次数为1的行 const uniqueRows = values.filter(row => countMap[row[2]] === 1); // 清空原区域并写入结果 range.clearContent(); if (uniqueRows.length > 0) { range.offset(0, 0, uniqueRows.length, uniqueRows[0].length).setValues(uniqueRows); } }
这段代码的逻辑:
- 先遍历所有行,统计每个C列值的出现次数
- 再筛选出那些C列值仅出现一次的行
- 最后清空原数据区域,把筛选后的唯一行写回去
这样不管是原始数据还是手动修改后的行,只要C列值是唯一的就会被保留,所有重复的行(包括原始条目)都会被移除。
内容的提问来源于stack exchange,提问作者Shabnum Zaidi
相关产品推荐
相关产品推荐

