使用宏验证Excel中的唯一复合键

时间:2013-02-21 14:20:48

标签: excel vba excel-vba

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

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

最好的方法是什么?

先谢谢

2 个答案:

答案 0 :(得分:3)

有几种方法可以实现这一目标:两种方法依赖于对数据进行排序,而第三种方法则不然。我将以不同的答案提供给他们,以便读者可以指出他们更喜欢哪些。

排序并应用条件格式

Pro:动态(调整数据更改),不需要任何代码 Con:需要排序,可能会变得混乱

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

    1. 突出显示所有数据,但从第一行数据开始
    2. 选择条件格式 - >新规则
    3. 将格式设置为红色填充
    4. 选择“使用公式确定要格式化的单元格”
    5. 以下是您需要的公式,假设选择从第2行开始(第1行中有标题),键列为A,B和C < / strong>即可。请仔细注意$符号出现的位置和不出现的位置:

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

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

答案 1 :(得分:3)

有几种方法可以实现这一目标:两种方法依赖于对数据进行排序,而第三种方法则不然。我将以不同的答案提供给他们,以便读者可以指出他们更喜欢哪些。

使用VBA中的词典

识别重复项

Pro:快,不需要排序
Con:需要代码,不会自动更新

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

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

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

如上所述,密钥比较区分大小写。如果您需要不区分大小写的匹配项,请将CompareModedctValues的{​​{1}}属性设置为dctDuplicates

注意:您需要添加对Microsoft Scripting Runtime的引用

TextCompare

用法:在A2:I5000中查找所有重复的行,使用A,B和E列作为关键列

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