使用列中的字符串在 table 中查找单词匹配以赋值

Use string in column to find a word match in table to assign value

我在 Sheet1 中查找 table 数据,其中 A 列和 B 列中的所有名称都是唯一的,因此 A 中的任何名称都不会存在于 B 中,反之亦然。但是,某些名称可能包含特殊字符,例如连字符或破折号,例如 O'neil 或 Jamie-lee

我在 Sheet2 中有另一个 table 数据,其中我需要使用 D 列中的文本字符串在 Sheet1 中(在 A 列或 B 列中)找到匹配的名称,然后分配分数如果在工作表 2 的 E 列中找到匹配项,工作表 1 上行的值。

我已经在 E 列中输入了匹配的分值,以证明我需要的结果。 我不介意使用 VBA 或适用于 XL2010

的 Excel 公式

是否可以使用文本字符串来查找单词匹配项,因为我只看到了相反的情况,还是我看错了?我只是似乎没有任何进展。

我经常更改代码,现在试图让它工作,我想我有点迷茫,但这是我的代码无法工作的当前状态:

Sub TextSearch()

    Dim LR As Long
        LR = ThisWorkbook.Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row

    Dim xLR As Long
        xLR = ThisWorkbook.Sheets("Sheet2").Range("A" & Rows.Count).End(xlUp).Row

    
    Dim oSht As Worksheet
    Dim Lastrow As Long
    Dim strSearch As String, Score As String
    Dim aCell As Range
    Dim i As Integer
    
    Set oSht = Sheets("Sheet1")
    Lastrow = oSht.Range("A" & Rows.Count).End(xlUp).Row
    
        
    With Sheets("Sheet2")
        'Loop from Lastrow to Firstrow (bottom to top)
        For Lrow = xLR To 2 Step -1
            'Get the value in the D column to perform search on
            With .Cells(Lrow, "D")
                If Not IsEmpty(.Value) Then
                    strSearch = .Value
                
                    Set aCell = oSht.Range("A1:B" & Lastrow).Find(What:=strSearch, LookIn:=xlValues, _
                                    LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
                                    MatchCase:=False, SearchFormat:=False)

                    For i = 2 To Lastrow
                        'Lookin column A on sheet1
                        If oSht.Cells(i, 1).Value = aCell Then
                            Score = oSht.Cells(i, 1).Offset(0, 2).Value
                            Sheets("Sheet2").Cells(Lrow, 4).Offset(0, 1).Value = Score
                        'Lookin Column B on sheet1
                        ElseIf oSht.Cells(i, 2).Value = aCell Then
                            Score = oSht.Cells(i, 2).Offset(0, 1).Value
                            Sheets("Sheet2").Cells(Lrow, 4).Offset(0, 1).Value = Score
                        End If
                    Next i
                
                
                End If
            End With
        Next Lrow
    End With

End Sub

这应该可以完成您尝试使用字典的操作。它根据 Sheet 1 上的 A 列和 B 列创建键,并将它们的分数存储为项目。

如果您在 Sheet 1 中有重复的名字,这不会失败,但它只会匹配遇到的名字。没有足够的数据来区分我能看到的东西。

Sub findmatches()
    Dim ws1 As Worksheet
    Dim ws2 As Worksheet
    Dim dict As Object
    Dim i As Long
    Dim lr As Long
    Dim name As String
    
    Set ws1 = Worksheets("Sheet1")
    Set ws2 = Worksheets("Sheet2")
    Set dict = CreateObject("Scripting.Dictionary")
    
    With ws1
        lr = .Cells(.Rows.Count, 1).End(xlUp).Row 'Getting last row
        For i = 2 To lr
            If Not dict.exists(.Cells(i, 1).Value) Then 'Checking if name is in dictionary
                dict.Add .Cells(i, 1).Value, .Cells(i, 3).Value 'Adding name and score
            End If
            If Not dict.exists(.Cells(i, 2).Value) Then 'Checking if name is in dictionary
                dict.Add .Cells(i, 2).Value, .Cells(i, 3).Value 'Adding name and score
            End If
        Next i
    End With
    
    With ws2
        lr = .Cells(.Rows.Count, 4).End(xlUp).Row
        For i = 2 To lr
            name = Split(.Cells(i, 4).Value, " ")(0) 'Splitting the string into an array and taking the first element
            If dict.exists(name) Then 'Checking if name is in dict
                .Cells(i, 5).Value = dict(name) 'assigning score to Column 5
            Else
                .Cells(i, 5).Value = 0 'No name score = 0
            End If
        Next i
    End With
End Sub

在 Excel 365 中,这可以通过(扩展的)数组公式实现。粘贴到E2并复制下来。

=LET(lookup,Sheet1!$C:$C,delimiter," ",string,$D2,array,Sheet1!$A:$B,data,INDEX(array,MOD(SEQUENCE(ROWS(array)*COLUMNS(array),,0),ROWS(array))+1,ROUNDUP(SEQUENCE(ROWS(array)*COLUMNS(array))/ROWS(array),0)),values,FILTERXML("<t><s>"&SUBSTITUTE(string,delimiter,"</s><s>")&"</s></t>","//s"),list,IFERROR(INDEX(lookup,1+MOD(MATCH(values,data,0)-1,ROWS(array))),0),TRANSPOSE(FILTER(list,list<>0)))

分解

=LET(lookup, Sheet1!$C:$C,
delimiter, " ",
string, $D2,
array, Sheet1!$A:$B,
data, INDEX(array,MOD(SEQUENCE(ROWS(array)*COLUMNS(array),,0),ROWS(array))+1,ROUNDUP(SEQUENCE(ROWS(array)*COLUMNS(array))/ROWS(array),0)),
values, FILTERXML("<t><s>"&SUBSTITUTE(string, delimiter,"</s><s>")&"</s></t>","//s"),
list, IFERROR(INDEX(lookup,1+MOD(MATCH(values,data,0)-1,ROWS(array))),0),
TRANSPOSE(FILTER(list, list<>0))
)

分配:

  • lookup 作为查找范围以获取结果的值
  • delimiterstring 作为要测试的句子以及如何将其拆分为动态数组
  • array 作为要测试的数据查找数组
  • dataarray 中所有值的计算一维数组堆叠
  • values 是根据您要测试的句子计算的一维数组
  • list 是找到匹配项的行 'indices' 的数组(mod #rows 所以它与列无关)

最后,该列表过滤掉所有未命中的内容,然后转置以提供来自 lookup 值的所有匹配项的溢出列表。