【问题标题】:Find matches of rows equalling over multiple columns查找等于多列的行的匹配项
【发布时间】:2023-03-04 16:49:01
【问题描述】:

我有一个工作表,我在其中安排玩家互相玩的游戏。每轮都有球员姓名或号码列。查看示例图片。Example Image

我所追求的是一种检查玩家之前是否玩过同一个玩家并突出显示该玩家姓名的方法。所以查找一个玩家和他的对手,看看它是否与其他列中的行匹配。

【问题讨论】:

  • 只有三轮吗?
  • 我的完整电子表格中实际上有 5 轮。

标签: excel indexing match lookup


【解决方案1】:

这可能很有趣,显然有不同的方法可以做到这一点,但如果没有 VBA,获得突出显示的单元格的方法是通过条件格式。

下面的示例显然已简化,但可以让您了解如何处理此问题。

  • 1) 我创建了一张包含三个圆形的表格,如下所示:

  • 2) 我在 B、D 和 F 列中添加了条件格式,以查看其右侧的单元格中是否包含最后输入的值。像这样:

    =$C4=INDIRECT(CELL("ADDRESS"))
    
  • 3) 显然,您需要对列 C、E 和 G 进行反转格式,如下所示:

    =$B=INDIRECT(CELL("ADDRESS"))
    
  • 4) 现在,当添加第 4 轮时(显然,当您想创建新行时,您可以调整格式),输入一个值并点击 ENTER

  • 5) 输出如下:

  • 6) 马特扮演过莎拉、艾玛和约翰

:)

EDIT1: 再次阅读您的问题,这并不是您所需要的。我会尝试调整它!

EDIT2: 请参阅下面我使用 VBA 的尝试,并实际回答您的问题 :)

  • 1) 利用VBA Worksheet Change Event:

    Private Sub Worksheet_Change(ByVal Target As Range)
    
    Dim Player As String, Opponent As String
    Dim C As Range
    
    'Check if a player name has been entered
    On Error Resume Next
    If InStr(1, Sheets(1).Cells(2, Target.Column), "Player", vbTextCompare) <> 0 Then
        If Right(Sheets(1).Cells(2, Target.Column).Value, 1) = "A" Then
            Opponent = Target.Offset(0, 2).Value
        ElseIf Right(Sheets(1).Cells(2, Target.Column).Value, 1) = "B" Then
            Opponent = Target.Offset(0, -2).Value
        End If
        Player = Target.Value
        If Opponent <> "" And Player <> "" Then
            Sheets(1).UsedRange.Cells.Interior.Pattern = xlNone
            With Sheets(1).UsedRange
                Set C = .Find(Opponent, Lookat:=xlWhole)
                If Not C Is Nothing Then
                    firstaddress = C.Address
                    Do
                        If C.Offset(0, 2).Value = Player Or C.Offset(0, -2).Value = Player Then
                            C.Interior.ColorIndex = 37
                        End If
                        Set C = .FindNext(C)
                    If C Is Nothing Then
                        GoTo Donefinding
                    End If
                    Loop While C.Address <> firstaddress
                End If
    Donefinding:
            End With
        End If
    End If
    
    End Sub
    
  • 2) 将此粘贴到 Sheet(1) 代码中

  • 3) 确保第 2 行具有“玩家 A”或“玩家 B”作为值

这段代码做了什么:

  • A - 它检查您是否将名称添加到玩家 A 或玩家 B
  • B - 如果是这样,它将首先清除之前运行中完成的所有格式
  • C - 然后使用.findnext 获取刚刚添加的玩家的任何匹配项
  • D - 根据 A 或 B in 将检查任何找到的单元格旁边的对手是否相同
  • E - 如果是这样,它将突出显示这些单元格

我确信代码可以进行一些清理,但它可以工作:)

【讨论】:

  • 感谢您的初次尝试。不过,我真正追求的是只强调玩家是否与同一个对手打过比赛。因此,例如 eI 完全填充下一轮,然后它强调实际上一场比赛实际上是之前发生的一场比赛。这样我就可以改变配对。如果这样更容易,我可以将 Visual Basic 脚本添加到 Excel,但我自己没有很多 VB 经验。
  • 使用 VBA 确实改变了很多...我会试试看 :)
  • @user3001454,我用一段 VBA 代码更新了答案。请试一试,告诉我它是否适合你。
  • 工作正常,虽然上面的另一个答案不使用 VBA,但我会选择它作为最终实现,因为其他人我将分享最终的工作表,以便不容易理解 VB。感谢您的努力 - 希望这是一个有趣的查询。
  • @user3001454,不客气,我根据您的需要更新了代码(查看数据的布局)。
【解决方案2】:

您可以使用条件格式来执行此操作。见下图:

这三个表分别称为 Round1、Round2、Round3。我添加了一个辅助列来保存条件格式公式,并将它们垂直堆叠,以便我可以截取适合此处的屏幕截图。

这是公式。请注意,它们必须使用 Ctrl+Shift+Enter 键盘快捷键输入数组:

H2:

=OR(
         [@[Player A]]&[@[Player B]]=Round2[Player A]&Round2[Player B],[@[Player B]]&[@[Player A]]=Round2[Player A]&Round2[Player B],
         [@[Player A]]&[@[Player B]]=Round3[Player A]&Round3[Player B],[@[Player B]]&[@[Player A]]=Round3[Player A]&Round3[Player B]
)

H8:

=OR(
         [@[Player A]]&[@[Player B]]=Round1[Player A]&Round1[Player B],[@[Player B]]&[@[Player A]]=Round1[Player A]&Round1[Player B],
         [@[Player A]]&[@[Player B]]=Round3[Player A]&Round3[Player B],[@[Player B]]&[@[Player A]]=Round3[Player A]&Round3[Player B]
)

H14:

=OR(
         [@[Player A]]&[@[Player B]]=Round1[Player A]&Round1[Player B],[@[Player B]]&[@[Player A]]=Round1[Player A]&Round1[Player B],
         [@[Player A]]&[@[Player B]]=Round2[Player A]&Round2[Player B],[@[Player B]]&[@[Player A]]=Round2[Player A]&Round2[Player B]
)

...这是您需要为第一个表添加到条件格式对话框中的内容:

这可以很容易地修改以处理更多轮次,但与通过 VBA 使用 Dictionary 对象相比,这是一种复杂且效率较低的方法。

【讨论】:

  • 完美,感谢您的出色回答。正是我想要的。
  • 酷。如果您觉得有帮助,请将答案标记为有用。
【解决方案3】:

这就是我自己使用 VBA 字典的方式。它处理表名称中包含字符串“Round”的任何表。

Option Explicit

Sub HighlightDuplicates()

Dim lo As ListObject
Dim lr As ListRow
Dim dic As Object
Dim ws As Worksheet
Dim sTemp As String
Dim sPlayerB As String
Dim sPlayerA As String

Set dic = CreateObject("Scripting.Dictionary")

For Each ws In ActiveWorkbook.Worksheets
    For Each lo In ws.ListObjects
        If InStr(lo.Name, "Round") Then
            lo.Range.Interior.Pattern = xlNone
            For Each lr In lo.ListRows
                sPlayerA = UCase(Intersect(lr.Range, lo.ListColumns("Player A").Range))
                sPlayerB = UCase(Intersect(lr.Range, lo.ListColumns("Player B").Range))
                If sPlayerA > sPlayerB Then
                    sTemp = sPlayerB
                    sPlayerB = sPlayerA
                    sPlayerA = sTemp
                End If
                sTemp = sPlayerA & "|" & sPlayerB
                If Not dic.exists(sTemp) Then
                    dic.Add sTemp, False
                Else
                    dic(sTemp) = True
                End If
            Next lr
        End If
    Next lo
Next ws


For Each ws In ActiveWorkbook.Worksheets
    For Each lo In ws.ListObjects
        If InStr(lo.Name, "Round") Then
            For Each lr In lo.ListRows
                sPlayerA = UCase(Intersect(lr.Range, lo.ListColumns("Player A").Range))
                sPlayerB = UCase(Intersect(lr.Range, lo.ListColumns("Player B").Range))
                If sPlayerA > sPlayerB Then
                    sTemp = sPlayerB
                    sPlayerB = sPlayerA
                    sPlayerA = sTemp
                End If
                sTemp = sPlayerA & "|" & sPlayerB
                If dic(sTemp) Then
                    Intersect(lr.Range, lo.ListColumns("Player A").Range).Interior.Color = vbYellow
                    Intersect(lr.Range, lo.ListColumns("Player B").Range).Interior.Color = vbYellow
                End If
            Next lr
        End If
    Next lo
Next ws

End Sub

结果如下:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多