我想在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)。
实现这一目标的最佳/最快方式是什么?
答案 0 :(得分:4)
使用以下sumproduct公式(或countifs)
添加条件格式 =SUMPRODUCT(($A$1:$A$6&$B$1:$B$6&$C$1:$C$6=$A1&$B1&$C1)*1)>1
<强>解释强>:
SUMPRODUCT
可以方便地使用在检查条件之前需要操作的范围。在这种情况下,我连接A,B和amp;跨越范围的C列,并将其与当前行的串联进行比较。然后我通过乘以1将TRUE / FALSE数组转换为1/0数组,SUM
的{{1}}部分将条件为真的行相加,得到重复的行(所有出现的) 。如果您的小范围,使用公式评估,您可以清楚地看到它是如何工作的。
这是一个快速修复,但性能并不理想,我用它来检测重复或生成序列号。
基于排序建议,需要添加键列,放入自动过滤器并对键进行排序,然后对键列进行条件化处理:
答案 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
假设起点是这样的:
一个ColumnA插入数字系列填充开始1
,Sheet2应该在删除重复后显示:
我认为就复制而言,要忽略ColumnE。
在源表中,选择数组(来自A1: - see!),例如A1:I6和HOME&gt;样式 - 条件格式,新规则...,使用公式确定哪个要格式化的单元格,此公式为真的格式值::
=$A1=MATCH($A1,Sheet2!$A:$A,0)>0
格式... ,填充,灰色,好的,好的。
对我而言:
答案 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