Excel如何按每3个重复值留1条的规则批量删除重复行
Excel自定义规则去重实现方案
你描述的去重规则可简化为相同值保留条数 = 该值总出现次数/3向上取整,对应关系如下:
- 出现1-2次:全部保留
- 出现3次:保留1条,删除2条
- 出现4-6次:保留2条
- 出现7-9次:保留3条
- 出现次数每增加3条,多保留1条,以此类推
该需求用函数公式、VBA、Excel内置Power Query均可实现,具体操作如下:
方法1:函数公式+筛选(无代码,适合单次临时处理)
假设判断重复的字段在A列,第一行为表头,数据从第2行开始:
- 在空白列(如D列,表头填「出现序号」)D2单元格输入公式,下拉填充至所有数据行:
=COUNTIF($A$2:A2,A2)
该公式用于标记当前行的A列值,是从数据开头到当前行的第几次出现。 - 在相邻空白列(如E列,表头填「总次数」)E2单元格输入公式,下拉填充:
=COUNTIF($A:$A,A2)
该公式用于统计每个重复值在A列的总出现次数。 - 在相邻空白列(如F列,表头填「是否保留」)F2单元格输入公式,下拉填充:
=IF(D2<=ROUNDUP(E2/3,0),"保留","删除") - 选中整表,开启筛选,筛选F列值为「删除」的行,选中后直接删除即可。
方法2:VBA脚本(适合批量重复处理,一键执行)
按Alt+F11打开VBA编辑器,右键点击当前工作簿名称选择「插入-模块」,粘贴以下代码后按F5运行即可,运行前建议备份原始数据:
Sub CustomRemoveDuplicates() Dim lastRow As Long, i As Long, dict As Object Dim keyCol As String, keepCount As Long, total As Long, k As Variant Dim hasHeader As Boolean, currentOrder As Long ' ------ 配置项,可根据实际表格修改 ------ keyCol = "A" ' 用于判断重复值的列,默认A列 hasHeader = True ' 表格第一行是否为表头 ' ------------------------------------ Set dict = CreateObject("Scripting.Dictionary") lastRow = Cells(Rows.Count, keyCol).End(xlUp).Row ' 统计每个值的总出现次数 For i = IIf(hasHeader, 2, 1) To lastRow k = Cells(i, keyCol).Value dict(k) = dict(k) + 1 Next i ' 从下往上遍历删除多余行,避免行号错乱 For i = lastRow To IIf(hasHeader, 2, 1) Step -1 k = Cells(i, keyCol).Value total = dict(k) keepCount = WorksheetFunction.RoundUp(total / 3, 0) currentOrder = Application.CountIf(Range(Cells(i, keyCol), Cells(lastRow, keyCol)), k) If currentOrder > keepCount Then Rows(i).Delete Next i Set dict = Nothing MsgBox "自定义去重完成" End Sub
方法3:Power Query(适合大数据量、需动态更新的场景)
- 选中原始数据区域,点击「数据」选项卡-「从表格/区域」,确认勾选「我的表格有标题」,导入Power Query编辑器。
- 点击「添加列」选项卡-「索引列」-「从1开始」,给每行添加顺序索引。
- 点击「转换」选项卡-「分组依据」,选择用于判断重复的列,分组操作选「所有行」,新列名可填「分组数据」,点击确定。
- 点击「添加列」-「自定义列」,输入公式:
= Table.FirstN([分组数据], Number.RoundUp(Table.RowCount([分组数据])/3))
公式作用为每个分组按原顺序取对应保留条数的行。 - 点击自定义列右上角的展开按钮,选择需要保留的字段,取消勾选「使用原始列名作为前缀」,点击确定。
- 删除索引、分组数据等辅助列,点击「主页」-「关闭并上载」即可将处理后的数据导出回Excel。后续原始数据更新时,右键点击结果表选择「刷新」即可自动重新计算。
待处理原始数据示例

去重后预期效果

内容的提问来源于stack exchange,提问作者gargilang
相关产品推荐
相关产品推荐

