我正在创建一个 excel 宏。作为其中的一部分,我需要验证 Excel 中的唯一复合键。即说 Column1 + Column2 + Column3 不应该重复。
如果是这样,该行应以红色突出显示。
最好的方法是什么?
提前致谢
有几种方法可以做到这一点:两种取决于对数据进行排序,而第三种则不是。我将提供不同的答案,以便读者可以指出他们更喜欢哪个。
优点:动态(根据数据变化进行调整),不需要任何代码
缺点:需要排序,可能会变得混乱
创建条件格式规则并将其应用于所有数据行。
这是您需要的公式,假设您的选择从第 2 行开始(第 1 行有一个标题),并且您的关键列是 A、B 和C。仔细注意$
标志出现的地方和不出现的地方:
=OR((CONCATENATE($A2,$B2,$C2)=CONCATENATE($A1,$B1,$C1)),
(CONCATENATE($A2,$B2,$C2)=CONCATENATE($A3,$B3,$C3)))
这将突出显示具有重复键的两行,或者如果有两个以上的行,则突出显示所有行。
有几种方法可以做到这一点:两种取决于对数据进行排序,而第三种则不是。我将提供不同的答案,以便读者可以指出他们更喜欢哪个。
优点:快速,不需要排序
缺点:需要代码,不会自动更新
在这种情况下,我将实际识别重复行的问题与突出显示它们的简单步骤分开处理。此函数返回一个字典,其中键是具有多行的复合键,值是包含与键匹配的所有行的行号的集合。它相当于Dictionary<string,List<int>>
.NET 中的 a。从概念上讲,它看起来像这样:
"some..key..1" : [1, 42, 401]
"some..key..2" : [134, 135]
键是每个键列的连接内容,由空字符分隔。我使用不可打印的空字符,以便键集(“A”、“Dog”、“2”)不等于(“AD”、“o”、“g2”)。
正如所写,关键比较是区分大小写的。如果您需要不区分大小写的匹配,请将 和 的属性CompareMode
设置为。dctValues
dctDuplicates
TextCompare
注意:您需要添加对 Microsoft Scripting Runtime 的引用
Public Function FindDuplicates(ByVal DataRange As Range, ParamArray KeyColumns()) As Dictionary
Dim ws As Worksheet
Dim vKeyRange, rngCol As Range
Dim dctKeys As New Dictionary
Dim colKeys
Dim keyParts() As String
Dim strKey As String
Dim dctValues As New Dictionary
Dim dctDuplicates As New Dictionary
Dim i As Long, ub As Long
Dim lngFirstRow As Long, lngLastRow As Long, lngRow As Long
Set ws = DataRange.Worksheet
' Identify unique key column numbers
For Each vKeyRange In KeyColumns
For Each rngCol In vKeyRange.Columns
dctKeys(rngCol.Column) = True
Next
Next
colKeys = dctKeys.Keys
ub = UBound(colKeys)
ReDim keyParts(ub)
' Find first and last row of data range
lngFirstRow = DataRange.Cells(1, 1).Row
lngLastRow = DataRange.Cells(DataRange.Rows.Count, 1).Row
' Loop through rows
For lngRow = lngFirstRow To lngLastRow
' Get the parts for the key
For i = 0 To ub
keyParts(i) = ws.Cells(lngRow, colKeys(i)).Value
Next
' Concatenate the parts with an unprintable character as
' the delimiter, so that "A" + "Dog" != "AD" + "og"
strKey = Join(keyParts, Chr(0))
' If the key hasn't been found yet, create a new collection
If Not dctValues.Exists(strKey) Then
dctValues.Add strKey, New Collection
End If
' Push the row number to the list of rows with this key
dctValues(strKey).Add lngRow
' If this is the second row with this key, add the
' list to the dictionary of keys with multiple rows
If dctValues(strKey).Count = 2 Then
dctDuplicates.Add strKey, dctValues(strKey)
End If
Next
Set FindDuplicates = dctDuplicates
End Function
用法:查找 A2:I5000 中所有重复的行,使用 A、B 和 E 列作为键列
Dim ws As Worksheet, dctDups As Dictionary, vKey, vRow
Set ws = ThisWorkbook.Worksheets(1)
Set dctDups = FindDuplicates(ws.Range("A2:I5000"), ws.Range("A:B"), ws.Range("E:E"))
For Each vKey In dctDups
For Each vRow In dctDups(vKey)
ws.Range("A" & vRow & ":I" & vRow).Interior.Color = vbRed
Next
Next