0

我正在创建一个 excel 宏。作为其中的一部分,我需要验证 Excel 中的唯一复合键。即说 Column1 + Column2 + Column3 不应该重复。

如果是这样,该行应以红色突出显示。

最好的方法是什么?

提前致谢

4

2 回答 2

3

有几种方法可以做到这一点:两种取决于对数据进行排序,而第三种则不是。我将提供不同的答案,以便读者可以指出他们更喜欢哪个。

排序和应用条件格式

优点:动态(根据数据变化进行调整),不需要任何代码
缺点:需要排序,可能会变得混乱

  1. 按关键列手动排序
  2. 创建条件格式规则并将其应用于所有数据行。

    1. 突出显示所有数据,但从第一行数据开始
    2. 选择条件格式 -> 新规则
    3. 将格式设置为红色填充
    4. 选择“使用公式确定要格式化的单元格”
    5. 这是您需要的公式,假设您的选择从第 2 行开始(第 1 行有一个标题),并且您的关键列是 A、B 和C。仔细注意$标志出现的地方和不出现的地方:

      =OR((CONCATENATE($A2,$B2,$C2)=CONCATENATE($A1,$B1,$C1)),
          (CONCATENATE($A2,$B2,$C2)=CONCATENATE($A3,$B3,$C3)))
      

      这将突出显示具有重复键的行,或者如果有两个以上的行,则突出显示所有行。

于 2013-02-21T14:53:46.207 回答
3

有几种方法可以做到这一点:两种取决于对数据进行排序,而第三种则不是。我将提供不同的答案,以便读者可以指出他们更喜欢哪个。

在 VBA 中使用字典识别重复项

优点:快速,不需要排序
缺点:需要代码,不会自动更新

在这种情况下,我将实际识别重复行的问题与突出显示它们的简单步骤分开处理。此函数返回一个字典,其中键是具有多行的复合键,值是包含与键匹配的所有行的行号的集合。它相当于Dictionary<string,List<int>>.NET 中的 a。从概念上讲,它看起来像这样:

"some..key..1" : [1, 42, 401]
"some..key..2" : [134, 135]

键是每个键列的连接内容,由空字符分隔。我使用不可打印的空字符,以便键集(“A”、“Dog”、“2”)不等于(“AD”、“o”、“g2”)。

正如所写,关键比较是区分大小写的。如果您需要不区分大小写的匹配,请将 和 的属性CompareMode设置为。dctValuesdctDuplicatesTextCompare

注意:您需要添加对 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
于 2013-02-21T18:19:00.233 回答