【问题标题】:VBA Loop to Highlight InconsistenciesVBA 循环突出不一致
【发布时间】:2014-04-23 18:25:21
【问题描述】:

我有一个包含两列(A 和 B)的电子表格。我想(FOR)循环遍历 B 列,直到两个或多个单元格值匹配。对于在 B 列中匹配的单元格,我想遍历它们在 A 列中的对应值。如果它们的对应值不相同,我希望所有涉及的行都被突出显示。

我知道它不正确/不完整,但以下是我想遵循的基本结构。非常感谢任何和所有帮助。谢谢。

Sub MySUb()
  Dim iRow As Integer

  For iRow = 2 To ActiveSheet.UsedRange.Rows.Count
    If Trim(range("A" & iRow)) <> "" And Trim(range("B" & iRow)) = Trim(range("B" & iRow)) Then
      range("A" & iRow, "B" & iRow).Interior.ColorIndex = 6
    End If
  Next
End Sub

【问题讨论】:

    标签: vba excel for-loop


    【解决方案1】:

    你可以先根据B列排序,然后修改你的代码为:

    Sub MySUb()
      Dim iRow As Integer
    
      For iRow = 1 To ActiveSheet.UsedRange.Rows.Count
        If Trim(Range("A" & iRow).Text) <> "" And _
        Trim(Range("B" & iRow).Text) = Trim(Range("B" & iRow + 1).Text) And _
        Trim(Range("A" & iRow).Text) <> Trim(Range("A" & iRow + 1).Text) Then
          Range("A" & iRow, "B" & iRow).Interior.ColorIndex = 6
          Range("A" & iRow + 1, "B" & iRow + 1).Interior.ColorIndex = 6
        End If
      Next
    End Sub
    

    编辑: 这是一个更好的解决方案,它可以处理在 B 列中有 >2 个匹配单元格但 A 中的相应单元格不匹配(即其中至少一个是不同的)的情况。在这种情况下,所有这些单元格都会被标记。

     Sub MySUb()
      Dim iRow As Integer
      Dim jRow As Integer
      Dim kRow As Integer
    
      For iRow = 1 To ActiveSheet.UsedRange.Rows.Count
        'If Trim(Range("A" & iRow).Text) <> "" Then
        For jRow = iRow To ActiveSheet.UsedRange.Rows.Count 'Finds the last non-matching item in B
         If Trim(Range("B" & jRow).Text) <> Trim(Range("B" & iRow).Text) Then
           Exit For
         End If
        Next jRow
        For kRow = iRow To jRow - 1
         If Trim(Range("A" & iRow).Text) <> Trim(Range("A" & kRow).Text) Then
          Range("A" & iRow, "B" & kRow).Interior.ColorIndex = jRow + 1 'Or can be 6
         End If
        Next kRow
      Next iRow
    End Sub
    

    【讨论】:

    • @Chicken_Hawk:你得到了什么错误?它适用于我的示例数据。
    • @Chicken_Hawk:我认为问题在于您的单元格值不是数字。试试我上面使用 .text 的更新代码
    • 非常接近,但没有考虑到 Col B 中的 >2 个匹配项和 Col A 中的两个或更多匹配项。
    • ^正是。而且 B 列中的值并不总是连续的。
    • @Chicken_Hawk:更新了解决方案。你说的顺序是什么意思?我的假设是您首先根据 B 列对行进行排序。
    【解决方案2】:

    这样的事情怎么样,使用字典跟踪 B 列中项目的实例,然后为 B 列值的每个唯一实例测试 A 列值。如果匹配失败,则标记所有实例。

    Sub DuplicateChecker()
        Dim rngColumnB As Range
            Set rngColumnB = Range("B2", Range("B2").End(xlDown))
        Dim rngCell As Range
        Dim rngDupe As Range
        Dim rngDuplicateB As Range
        Dim dctValuesChecked As Dictionary 
            'requires enabled reference library for 'Microsoft Scripting Runtime'
            Set dctValuesChecked = New Dictionary
        Dim strColumnAValue As String
    
        For Each rngCell In rngColumnB
            strColumnAValue = rngCell.Offset(0, -1).Value
            If Not dctValuesChecked.Exists(Trim(rngCell.Value)) Then
                Call dctValuesChecked.Add(rngCell.Value, rngCell.Row)
            Else
                Set rngDuplicateB = FindItemsInRange(rngCell.Value, rngColumnB)
                rngDuplicateB.EntireRow.Select
                For Each rngDupe In rngDuplicateB
                    If Not rngDupe.Offset(0, -1).Value = strColumnAValue Then
                        rngDuplicateB.Interior.ColorIndex = 6
                        rngDuplicateB.Offset(0, -1).Interior.ColorIndex = 6
                    End If
                Next rngDupe
            End If
        Next rngCell
    End Sub
    
    Function FindItemsInRange(varItemToFind As Variant, _
                                rngSearchIn As Range, _
                                Optional LookIn As XlFindLookIn = xlValues, _
                                Optional LookAt As XlLookAt = xlPart, _
                                Optional blnMatchCase As Boolean = False) As Range
    
    'adapted from a function by Aaron Blood found on the Ozgrid forums:
    'http://www.ozgrid.com/forum/showthread.php?t=27240
    
        With rngSearchIn
            Dim rngFoundItems As Range
                Set rngFoundItems = .Find(What:=varItemToFind, _
                                                LookIn:=LookIn, _
                                                LookAt:=LookAt, _
                                                SearchOrder:=xlByRows, _
                                                SearchDirection:=xlNext, _
                                                MatchCase:=blnMatchCase, _
                                                SearchFormat:=False)
    
            If Not rngFoundItems Is Nothing Then
                Set FindItemsInRange = rngFoundItems
                Dim strAddressOfFirstFoundItem As String
                    strAddressOfFirstFoundItem = rngFoundItems.Address
                Do
                    Set FindItemsInRange = Union(FindItemsInRange, rngFoundItems)
                    Set rngFoundItems = .FindNext(rngFoundItems)
                Loop While Not rngFoundItems Is Nothing And _
                                rngFoundItems.Address <> strAddressOfFirstFoundItem
            End If
        End With
    End Function
    

    【讨论】:

    • 谢谢卡尔!这似乎有效,但它给了我一个运行时错误 457。“此键已与此集合的元素相关联”
    • 一直在研究这个,假设当你点击调试按钮时它会突出显示Call dctValuesChecked.Add(rngCell.Value, rngCell.Row)。我不确定这是怎么发生的,因为它只会在 rngCell.Value 键不存在时添加。您是否在多个工作表或工作簿上运行此程序而不结束子程序?如果是这样,请尝试在 Next rngCell 之后添加 Set dctValuesChecked = Nothing
    猜你喜欢
    • 2011-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-26
    • 1970-01-01
    • 2016-01-02
    • 2012-03-13
    • 1970-01-01
    相关资源
    最近更新 更多