将 A 列中按空格分割的单词与 B 列中的字符串进行比较,如果 A 列中的所有单词都存在于 B 列的任何字符串中,则返回匹配

Compare words split by space in column A to strings in column B and return match if all the words in column A are present in any string in column B

提问人:Tan 提问时间:10/12/2022 最后编辑:CommunityTan 更新时间:1/2/2023 访问量:140

问:

文档图像
enter image description here

在第一个单元格中,有文本“Wei J 2020”。
VBA代码应在B列中存在的所有字符串中搜索此文本中的所有单词“Wei”,“J”和“2020”。
如果所有这些单词都存在于一个字符串中,则应突出显示 A 列中的文本,该文本定义它是匹配项。

A1 中的所有单词都与 B2 中的字符串匹配。

Private Sub CompareWords()

    Dim xStr() As String
    Dim i As Long
    Dim x As Long, y As Long

    With ActiveSheet
        For i = 1 To .Cells(.Rows.Count, "A").End(xlUp).Row
            xStr = Split(.Cells(i, "A").Value, " ")
            With .Cells(i, "B")
                For x = LBound(xStr()) To UBound(xStr())
                    For y = 1 To Len(.Text)
                        If Mid(.Text, y, Len(xStr(x))) = xStr(x) Then
                            .Characters(y, Len(xStr(x))).Font.ColorIndex = 3
                        End If
                    Next y
                Next x
            End With
        Next i
    End With 
End Sub

我能够比较 A1 和 B1、A2 和 B2 中的单词等等。
如果字符串存在于同一行中,则结果

enter image description here

但要求是在 B 列中存在的所有字符串中找到 A1 中的单词,并且仅当所有单词都存在于同一字符串中时才返回匹配项。

此外,如果匹配项,此代码会将 B 列中的字体颜色更改为红色。
如果 A 列中的单词是匹配的,我们可以突出显示它吗?

Excel VBA 拆分 比较 匹配

评论

0赞 JvdV 10/12/2022
你有 markdown sampledata 可以使用吗?还有解决这个问题的公式呢?而且,这些子字符串中的任何一个都是一个更大的子字符串的一部分,换句话说:误报。在您的示例中,您在“MJ”中找到了“J”。
0赞 FaneDuru 10/12/2022
“如果所有单词都存在于同一个字符串中”是什么意思?最好还张贴一张图片,显示您希望该系列在处理后看起来如何
1赞 FunThomas 10/12/2022
如果您复制代码 1:1,最好至少给作者一个链接。stackoverflow.com/a/56581646/7599798
0赞 FaneDuru 10/12/2022
你真的需要一个答案,一个解决问题的方法吗?你能回答我一个多小时前提出的澄清问题吗?
0赞 Tan 10/12/2022
@JvdV 请在下面找到工作簿的链接 docs.google.com/spreadsheets/d/..., 此外,假阳性结果很少见,因为只有当每个单词(例如:“Wei”、“J”和“2020”)出现在 B 列中的一个字符串中时,才会返回匹配项

答:

0赞 FaneDuru 10/12/2022 #1

请测试下一个改编的代码。它将根据 B:B 中的所有单元格检查 A:A 中单元格中的相同拆分字符串,并将找到完全匹配的单元格涂成黄色(单词顺序无关紧要):

Sub CompareWords()
    Dim ws As Worksheet, lastR As Long, xStr() As String, arrMtch() As String, arrAddress() As String, rngYellow As Range
    
    Dim i As Long, j As Long
    Dim x As Long, y As Long

    Set ws = ActiveSheet
    lastR = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    ReDim arrAddress(1 To lastR, 1 To 1) 'array to keep the addresses of cells from B:B where a match has been found
    
    'reset the columns appearence:
    ws.Range("A1:A" & lastR).Interior.Color = xlNone
    ws.Range("B1:B" & ws.Range("B" & ws.Rows.Count).End(xlUp).Row).Font.ColorIndex = xlAutomatic
    ws.Range("C1:C" & ws.Range("B" & ws.Rows.Count).End(xlUp).Row).ClearContents
    
    Application.ScreenUpdating = False: Application.Calculation = xlCalculationManual
    With ws
        For i = 1 To lastR
            xStr = Split(.Cells(i, "A").Value, " ")
            For j = 1 To .Cells(.Rows.Count, "B").End(xlUp).Row
                With .Cells(j, "B")
                    ReDim arrMtch(UBound(xStr)) 'redim the array keeping "OK" for all matches
                    For x = LBound(xStr()) To UBound(xStr())
                        For y = 1 To Len(.Text)
                            If Mid(.Text, y, Len(xStr(x))) = xStr(x) Then
                                 arrMtch(x) = "OK"
                            End If
                        Next y
                    Next x
                    If UBound(Filter(arrMtch, "OK", True)) = UBound(arrMtch) Then 'if all array elements are "OK"
                        addToRange rngYellow, ws.Cells(i, "A") 'place the cell in a Union range
                        arrAddress(i, 1) = .Address                       'place the cell from B:B address in the dedicated array
                        Exit For
                    End If
                End With
            Next j
        Next i
    End With
    If Not rngYellow Is Nothing Then rngYellow.Interior.Color = vbYellow
    ws.Range("C1").Resize(UBound(arrAddress), 1).Value = arrAddress
    Application.ScreenUpdating = True: Application.Calculation = xlCalculationAutomatic
    MsgBox "Ready..."
End Sub

上面的代码在 C:C 列中写入 B:B 中单元格的地址,其中已找到匹配项。

请在相应的工作表代码模块中复制下一个事件代码。双击 A:A 中的(黄色)单元格时,B:B 中的匹配单元格在匹配的单词上显示颜色(红色):

Option Explicit

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    If Target.Column = 1 Then
        If Target.Offset(, 2) <> "" Then
               Dim xStr() As String, x As Long, y As Long
                xStr = Split(Target.Value, " ")
                With Me.Range(Target.Offset(, 2).Value)
                        .Font.ColorIndex = xlAutomatic 'color the cell font in black
                        For x = LBound(xStr()) To UBound(xStr())
                            For y = 1 To Len(.Text)
                                    If Mid(.Text, y, Len(xStr(x))) = xStr(x) Then
                                        .Characters(y, Len(xStr(x))).Font.ColorIndex = 3
                                    End If
                                Next y
                        Next x
                        .Select
                End With
                Cancel = True
         End If
     End If
End Sub

评论

0赞 Tan 10/13/2022
感谢您@FaneDuru回答,但您提供的代码是将拆分字符串中的每个单词与 B 列中的所有单元格进行比较以提供单独的匹配,但根据我的要求,拆分字符串中的所有单词(如“Wei”、“J”和“2020”)都应该在 B:B 列中搜索, 但只有当所有 3 个单词都存在于 B 列中一个单元格的同一字符串中时,它才应该显示匹配项。我希望你能理解...请参阅下图(预期结果)供参考 imgur.com/a/p3iOEWq
0赞 FaneDuru 10/13/2022
请从这里下载一个示例工作簿,其独特的工作表上有一个按钮。按下它,范围将按照(我理解)您需要的方式进行处理。我的意思是,A:A 中在 B:B 中具有(完全)匹配的单元格是黄色的,匹配单元格形式 B:B 的地址是用 C:C 写的。 双击 A:A 中的黄色单元格,将突出显示 B:B 中相应匹配单元格中的单词。该链接有效期为 7 天...
0赞 Tan 10/13/2022
代码运行良好,您为我提供的比我要求的更多。非常感谢你,我感谢你的帮助。
0赞 FaneDuru 10/13/2022
@Tan 很高兴我能帮上忙!1. 很高兴了解到,一个好的问题是帮助我们清楚地了解您尝试完成的任务。从这个角度来看,你的问题不是那么好,至少在我的口味上......2. 通过一些测试,我观察到在某些情况下,B:B 中可能不止一次出现。现在,代码在找到第一个循环(B:B 单元格)后存在。返回 conde 发现的尽可能多的事件是否有用?我的意思是,他们在 C:C 中的地址。代码会慢一点,但这是可以做到的。此外,双击事件可在 C:C 中的更多地址上运行
0赞 FaneDuru 10/13/2022
@Tan 还有别的东西:作为这里的新用户,我想告诉你,我们在这里,当有人以方便的方式回答我们的问题时,勾选代码左侧复选框,以使其被接受。这样,搜索类似问题的其他人就会知道提供的解决方案有效......