【问题标题】:Delete ALL duplicate rows based on multiple columns删除基于多列的所有重复行
【发布时间】:2013-06-13 13:39:30
【问题描述】:

下面的代码目前正在删除 A 列中的所有重复项,包括原始代码。我想修改下面的代码以删除基于 A、B、C 和 D 列的所有重复项。澄清一下,对于行1 和 2 如果列 A 匹配,B 匹配,c 匹配和 d 匹配两行将被删除。有人可以提供帮助吗?我相信这里需要一个数组,但不确定如何。谢谢!

Dim toDel5(), p As Long
Dim RNG5 As Range, Cell5 As Long
Set RNG5 = Range("a1:a4000") 'set your range here

For Cell5 = 1 To RNG5.Cells.Count
    If Application.CountIf(RNG5, RNG5(Cell5)) > 1 Then
        ReDim Preserve toDel5(p)
        toDel5(p) = RNG5(Cell5).Address
        p = p + 1
    End If
Next

On Error GoTo NO_DUPLICATES
For p = UBound(toDel5) To LBound(toDel5) Step -1
    Range(toDel5(p)).EntireRow.Delete

Next p
On Error GoTo 0


End With 
NO_DUPLICATES:

【问题讨论】:

  • 如果你使用的是 xl2007+ 那么你可以使用RemoveDuplicates

标签: arrays excel vba duplicates


【解决方案1】:

这个问题似乎需要自定义算法。不确定上述RemoveDuplicates 是否可以为不那么简单的情况提供可靠的答案,但在这种情况下,我更喜欢从头开始创建一些东西。就您的代码不太灵活而言,我找不到提出更正的方法,因此我创建了整个循环(我不应该做的事情)。请注意,此代码可以适应任何数量的分析列/行。还要记住,它依赖于目标单元格的按时删除(而不是删除整行,只能在循环之外完成);这只是向您展示另一种替代解决方案;您可以随意更改此代码。

Dim maxRow As Long
Dim curStep, startColumn, endColumn As Integer
Dim areDuplicated As Boolean
curStep = 2 'No of rows to be considered
startColumn = 1
endColumn = 4
maxRow = 4000
For curRow = 1 To maxRow - 1
    areDuplicated = True
    For curColumn = startColumn To endColumn
        For curRow2 = curRow + 1 To curRow + curStep - 1
           If (IsEmpty(RNG5.Cells(curRow, curColumn)) Or RNG5.Cells(curRow, curColumn) <> RNG5.Cells(curRow2, curColumn)) Then
              areDuplicated = False
              Exit For
           End If

           If (Not areDuplicated) Then
              Exit For
           End If
        Next
    Next

    If (areDuplicated) Then
        For curRow3 = curRow To curRow + curStep - 1
            For curCol3 = startColumn To endColumn
                RNG5.Cells(curRow3, curCol3).Value = ""
            Next
        Next
    End If
Next

【讨论】:

    【解决方案2】:

    感谢 Varocarbas,这比我最终使用的代码要简单一些。我使用的代码如下,以防有人想看到另一个选项。感谢您的帮助!

    Dim r As Long, c As Long, n As Long, x As Long  
    Dim rData As Range 
    
    Application.ScreenUpdating = False 
    n = ActiveSheet.Cells(1, 1).CurrentRegion.Columns.Count + 1 
    ActiveSheet.Cells(1, n).Value = "TEMP" 
    
    For r = 2 To ActiveSheet.Cells(1, 1).CurrentRegion.Rows.Count 
        ActiveSheet.Cells(r, n).Value = r 
    Next r 
    
    Set rData = ActiveSheet.Cells(1, 1).CurrentRegion 
    
    With ActiveSheet.Sort 
        .SortFields.Clear 
    
        For c = 1 To n
            .SortFields.Add Key:=rData.Cells(1, c).Resize(rData.Rows.Count - 1, 1) 
        Next c 
    
        .SetRange rData 
        .Header = xlYes 
        .MatchCase = False 
        .Orientation = xlTopToBottom 
        .SortMethod = xlPinYin 
        .Apply 
    End With 
    
    With rData 
        For r = 2 To .Rows.Count 
             x = 0 
             For c = 1 To n
                If .Cells(r, c).Value <> .Cells(r + 1, c).Value Then 
                    x = x + 1 
                    Exit For 
                End If 
                 Next c 
             If x = 0 Then 
                .Cells(r, n).Value = True 
                .Cells(r + 1, n).Value = True 
            End If     
        Next r 
    End With 
    
    With ActiveSheet.Sort 
        .SortFields.Clear 
        .SortFields.Add Key:=rData.Cells(1, n).Resize(rData.Rows.Count - 1, 1) 
        .SetRange rData 
        .Header = xlYes 
        .MatchCase = False 
        .Orientation = xlTopToBottom 
        .SortMethod = xlPinYin 
        .Apply 
    End With 
    
    On Error Resume Next 
    rData.Columns(n).SpecialCells(xlCellTypeConstants, xlLogical).EntireRow.Delete 
    On Error Goto 0 
    
    rData.Columns(n).EntireColumn.Delete 
    Application.ScreenUpdating = True
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-03
      • 2018-03-07
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多