突出显示重复的行

时间:2015-05-31 15:01:17

标签: excel vba performance loops

我想在Excel VBA中突出显示重复的行。假设我有以下示例表,其中包含用于测试的列A,B,C和D:

 A       B       C       D (Strings)

 1       1       1       dsf
 2       3       5       dgdgdgdg
 1       1       1       dsf
 2       2       2       xxx
 6       3       4       adsdadad
 2       2       2       xxx

重复的行应以任何颜色突出显示,例如灰色。我看起来非常适合快速执行的代码,因为它将用于相当大的表。 请注意,有可用于突出显示重复单元格(但不是重复行)的解决方案。我不知道如何识别行是否重复,同时如何快速地识别行,即没有嵌套循环。解决方案应该是VBA(而不是Excel)。

实现这一目标的最佳/最快方式是什么?

5 个答案:

答案 0 :(得分:4)

使用以下sumproduct公式(或countifs)

添加条件格式

=SUMPRODUCT(($A$1:$A$6&$B$1:$B$6&$C$1:$C$6=$A1&$B1&$C1)*1)>1

conditional formatting

<强>解释

SUMPRODUCT可以方便地使用在检查条件之前需要操作的范围。在这种情况下,我连接A,B和amp;跨越范围的C列,并将其与当前行的串联进行比较。然后我通过乘以1将TRUE / FALSE数组转换为1/0数组,SUM的{​​{1}}部分将条件为真的行相加,得到重复的行(所有出现的) 。如果您的小范围,使用公式评估,您可以清楚地看到它是如何工作的。

这是一个快速修复,但性能并不理想,我用它来检测重复或生成序列号。

ponydeer建议的评论解决方案 - 更高的性能

基于排序建议,需要添加键列,放入自动过滤器并对键进行排序,然后对键列进行条件化处理:

Sorted

答案 1 :(得分:3)

首先对所有列进行排序

 Workbooks(1).Sheets(1).Range("A:C").Sort Key1:=Workbooks(1).Sheets(1).Range("A:A"), Order1:=xlAscending, Key2:=Workbooks(1).Sheets(1).Range("B:B"), Order2:=xlAscending, Key3:=Workbooks(1).Sheets(1).Range("C:C"), Order3:=xlAscending, Orientation:=xlSortRows

然后遍历所有行并将它们与上面的行进行比较

 Dim a As Application
 Set a = Application

 For i=1 to 1000 ' here you need to set the number of rows you have
   if Join(a.Transpose(a.Transpose(ActiveSheet.Rows(i).Value)), Chr(0)) = _
   Join(a.Transpose(a.Transpose(Sheets(1).Rows(i+1).Value)), Chr(0)) then

      Sheets(1).Range(i+1 & ":" & i+1).EntireRow.Interior.Color = 49407

   end if

 Next i

两行的比较基于这个主题:How to compare two entire rows in a sheet

请插入工作簿,工作表的名称,并自行设置代码范围和限制。

答案 2 :(得分:2)

我认为最快/最好将取决于重复的比例 - 只有一行应该比示例中的50%更快 - 以及数组的实际大小(创建密钥的列数等等) )。

鉴于很少有可能用'纯'VBA击败内置函数我怀疑使用UI,如果需要,在VBA内,在某些情况下会更快。例如:

添加一个索引列(系列填充将提供),复制整个工作表(比如Sheet2),将删除重复项应用于除索引列以外的所有列,然后将此类CF公式规则应用于原始工作表的相关范围:< / p>

=$A1=MATCH($A1,Sheet2!$A$1:$A$3000,0)>0  

假设起点是这样的:

SO30558893 first example

一个ColumnA插入数字系列填充开始1,Sheet2应该在删除重复后显示:

SO30558893 second example

我认为就复制而言,要忽略ColumnE。

在源表中,选择数组(来自A1: - see!),例如A1:I6和HOME&gt;样式 - 条件格式,新规则...,使用公式确定哪个要格式化的单元格此公式为真的格式值:

=$A1=MATCH($A1,Sheet2!$A:$A,0)>0  

格式... ,填充,灰色,好的,好的。

对我而言:

SO30558893 third example

答案 3 :(得分:2)

我已经从OP的评论中对样本文件link测试了3种不同的方法。可能VBA的实现并不是最优的,但下面是平均时间为100次的结果:

1)条件格式使用:

a)SUMPRODUCT连接列 - 3s

b)COUNTIFS,完整列参考 - 1.9s

c)COUNTIFS引用已使用的范围 - 0.2s

2)对所有列的范围进行排序,逐行比较,排序 - 0.3s

3)使用高级过滤器3.5s

以下是最快方法的代码:

Sub CF1()

    Application.ScreenUpdating = False

    Dim sFormula As String
    Dim rRng As Range
    Dim nCol As Integer, i As Integer

    Set rRng = Range("A1").CurrentRegion
    nCol = rRng.Columns.Count

    'build the formula
    sFormula = "=COUNTIFS("

    For i = 1 To nCol
      sFormula = sFormula & rRng.Columns(i).Address & "," & _
         rRng.Cells(1, i).Address(False, True)
      If i < nCol Then sFormula = sFormula & ","
    Next
    sFormula = sFormula & ")>1"

    'write the formula in helper cell to get it's local version
    rRng.Cells(1, nCol + 1).Formula = sFormula

    rRng.FormatConditions.Delete
    With rRng.FormatConditions.Add(Type:=xlExpression, _
            Formula1:=rRng.Cells(1, nCol + 1).FormulaLocal)
       .Interior.ThemeColor = xlThemeColorAccent3
    End With

    rRng.Cells(1, nCol + 1).Clear

    Application.ScreenUpdating = True
End Sub

答案 4 :(得分:0)

patterns