2012-06-15 18:29:24 +0000 2012-06-15 18:29:24 +0000
14
14
Advertisement

Excelで類似したテキスト文字列を比較する

Advertisement

私は現在、2つの別々のデータソースからの「名前」フィールドを照合しようとしています。完全には一致しませんが、一致しているとみなされるには十分近い名前がいくつかあります(以下の例)。自動一致の数を改善する方法について、何かアイデアはありますか?私はすでに一致基準からミドルイニシャルを除外しています。

=IFERROR(IF(LEFT(SYSTEM A,IF(ISERROR(SEARCH(" ",SYSTEM A)),LEN(SYSTEM A),SEARCH(" ",SYSTEM A)-1))=LEFT(SYSTEM B,IF(ISERROR(SEARCH(" ",SYSTEM B)),LEN(SYSTEM B),SEARCH(" ",SYSTEM B)-1)),"",IF(LEFT(SYSTEM A,FIND(",",SYSTEM A))=LEFT(SYSTEM B,FIND(",",SYSTEM B)),"Last Name Match","RESEARCH")),"RESEARCH")

現在の一致式。

Advertisement
Advertisement

回答 (7)

12
12
12
2012-06-15 18:51:25 +0000

Microsoft Fuzzy Lookup Addin](http://www.microsoft.com/en-us/download/details.aspx?id=15011)の使用を検討してみてはいかがでしょうか。

MSのサイトより。

概要

Excel用ファジィルックアップアドインは、Microsoft Researchによって開発されたもので、Microsoft Excelのテキストデータのファジィマッチングを行います。このアドインは、単一のテーブル内でファジー重複行を識別したり、2つの異なるテーブル間で類似した行をファジー結合したりするために使用できます。マッチングは、スペルミス、略語、同義語、追加/欠落したデータなど、さまざまなエラーに対してロバストです。例えば、"Mr. Andrew Hill"、"Hill, Andrew R.“、"Andy Hill "の行がすべて同じエンティティを参照していることを検出し、それぞれの一致に応じて類似度スコアを返します。デフォルトの設定では、製品名や顧客の住所など、さまざまなテキストデータに対応していますが、特定のドメインや言語に合わせてマッチングをカスタマイズすることもできます。

6
6
6
2012-06-15 19:47:53 +0000

一般的な短縮形を取り除くために、 this リスト(英語セクションのみ)を使うことを検討してみましょう。

追加で、2つの文字列がどのくらい「近い」かを正確な言葉で教えてくれる関数の使用を検討してみてはいかがでしょうか。以下のコードは、 ここ から来たもので、 smirkingman に感謝します。

Option Explicit
Public Function Levenshtein(s1 As String, s2 As String)

Dim i As Integer
Dim j As Integer
Dim l1 As Integer
Dim l2 As Integer
Dim d() As Integer
Dim min1 As Integer
Dim min2 As Integer

l1 = Len(s1)
l2 = Len(s2)
ReDim d(l1, l2)
For i = 0 To l1
    d(i, 0) = i
Next
For j = 0 To l2
    d(0, j) = j
Next
For i = 1 To l1
    For j = 1 To l2
        If Mid(s1, i, 1) = Mid(s2, j, 1) Then
            d(i, j) = d(i - 1, j - 1)
        Else
            min1 = d(i - 1, j) + 1
            min2 = d(i, j - 1) + 1
            If min2 < min1 Then
                min1 = min2
            End If
            min2 = d(i - 1, j - 1) + 1
            If min2 < min1 Then
                min1 = min2
            End If
            d(i, j) = min1
        End If
    Next
Next
Levenshtein = d(l1, l2)
End Function

これが何をするかというと、もう一方の文字列にたどり着くために、一方の文字列に何回挿入と削除をしなければならないかを教えてくれます。私はこの数値を低く抑えるようにしています(そして、苗字は正確でなければなりません)。

5
Advertisement
5
5
2015-10-09 14:26:12 +0000
Advertisement

私はあなたが使える(長い)式を持っています。これは上記のものほど洗練されていませんし、フルネームではなく苗字でしか使えませんが、役に立つかもしれません。

ヘッダー行があり、A2B2 を比較したい場合は、その行の他のセル(例:C2)にこれを配置し、最後までコピーします。

=IF(A2=B2, “EXACT”,IF(SUBSTITUTE(A2,“-”,“ ”)=SUBSTITUTE(B2,“-”,“ ”), “ハイフン”,IF(LEN(A2)>LEN(B2),IF(LEN(A2)>LEN(SUBSTITUTE(A2,B2,“)), "全文字列”,IF(MID(A2,1. 1)=MID(B2,1,1),1,0)+IF(MID(A2,2,1)=MID(B2,2,1),1,0)+IF(MID(A2,3,1)=MID(B2,3,1),1,0)+IF(MID(A2,LEN(A2),1)=MID(B2,LEN(B2),1),1,0)+IF(MID(A2,LEN(A2)-1,1)=MID(B2,LEN(B2)-1,1),1, 0)+IF(MID(A2,LEN(A2)-2,1)=MID(B2,LEN(B2)-2,1),1,0)&“°”),IF(LEN(B2)>LEN(SUBSTITUTE(B2,A2,“”), “文字列全体”,IF(MID(A2,1,1)=MID(B2,1,1),1,0)+IF(MID(A2,2,1)=MID(B2,2,1),1. 0)+IF(MID(A2,3,1)=MID(B2,3,1),1,0)+IF(MID(A2,LEN(A2),1)=MID(B2,LEN(B2),1),1,0)+IF(MID(A2,LEN(A2)-1,1)=MID(B2,LEN(B2)-1,1),1,0)+IF(MID(A2,LEN(A2)-2,1)=MID(B2,LEN(B2)-2,1),1,0)&“°”))))

これは返します。

  • EXACT - 完全一致の場合
  • ハイフン - ダブルバレルの名前のペアで、片方がハイフン、もう片方がスペースの場合
  • 全文字列 - 片方の名字のすべてがもう片方の名字の一部である場合(例:SmithがFrench-Smithになった場合)

その後、両者の比較点の数に応じて、0°から6°までの度合いを返します(つまり、6°の方がよく比較されます)。(つまり、6°の方が比較しやすい)。

私が言ったように、少し大雑把で準備ができていますが、うまくいけば大体のボールパークに入ることができるでしょう。

2
2
2
2016-06-23 06:12:19 +0000

似たようなものを探していて 私は以下のコードを見つけました。

Abracadabra/アブラカダブラで91%、Hollywood Street/Hollyhood Strで75%、Florence/Franceで62%、Disneylandで0%を返します

あなたが望んでいたものに十分近いと思います :)

Public Function Similarity(ByVal String1 As String, _
    ByVal String2 As String, _
    Optional ByRef RetMatch As String, _
    Optional min_match = 1) As Single
Dim b1() As Byte, b2() As Byte
Dim lngLen1 As Long, lngLen2 As Long
Dim lngResult As Long

If UCase(String1) = UCase(String2) Then
    Similarity = 1
Else:
    lngLen1 = Len(String1)
    lngLen2 = Len(String2)
    If (lngLen1 = 0) Or (lngLen2 = 0) Then
        Similarity = 0
    Else:
        b1() = StrConv(UCase(String1), vbFromUnicode)
        b2() = StrConv(UCase(String2), vbFromUnicode)
        lngResult = Similarity_sub(0, lngLen1 - 1, _
        0, lngLen2 - 1, _
        b1, b2, _
        String1, _
        RetMatch, _
        min_match)
        Erase b1
        Erase b2
        If lngLen1 >= lngLen2 Then
            Similarity = lngResult / lngLen1
        Else
            Similarity = lngResult / lngLen2
        End If
    End If
End If

End Function

Private Function Similarity_sub(ByVal start1 As Long, ByVal end1 As Long, _
                                ByVal start2 As Long, ByVal end2 As Long, _
                                ByRef b1() As Byte, ByRef b2() As Byte, _
                                ByVal FirstString As String, _
                                ByRef RetMatch As String, _
                                ByVal min_match As Long, _
                                Optional recur_level As Integer = 0) As Long
'* CALLED BY: Similarity *(RECURSIVE)

Dim lngCurr1 As Long, lngCurr2 As Long
Dim lngMatchAt1 As Long, lngMatchAt2 As Long
Dim I As Long
Dim lngLongestMatch As Long, lngLocalLongestMatch As Long
Dim strRetMatch1 As String, strRetMatch2 As String

If (start1 > end1) Or (start1 < 0) Or (end1 - start1 + 1 < min_match) _
Or (start2 > end2) Or (start2 < 0) Or (end2 - start2 + 1 < min_match) Then
    Exit Function '(exit if start/end is out of string, or length is too short)
End If

For lngCurr1 = start1 To end1
    For lngCurr2 = start2 To end2
        I = 0
        Do Until b1(lngCurr1 + I) <> b2(lngCurr2 + I)
            I = I + 1
            If I > lngLongestMatch Then
                lngMatchAt1 = lngCurr1
                lngMatchAt2 = lngCurr2
                lngLongestMatch = I
            End If
            If (lngCurr1 + I) > end1 Or (lngCurr2 + I) > end2 Then Exit Do
        Loop
    Next lngCurr2
Next lngCurr1

If lngLongestMatch < min_match Then Exit Function

lngLocalLongestMatch = lngLongestMatch
RetMatch = ""

lngLongestMatch = lngLongestMatch _
+ Similarity_sub(start1, lngMatchAt1 - 1, _
start2, lngMatchAt2 - 1, _
b1, b2, _
FirstString, _
strRetMatch1, _
min_match, _
recur_level + 1)
If strRetMatch1 <> "" Then
    RetMatch = RetMatch & strRetMatch1 & "*"
Else
    RetMatch = RetMatch & IIf(recur_level = 0 _
    And lngLocalLongestMatch > 0 _
    And (lngMatchAt1 > 1 Or lngMatchAt2 > 1) _
    , "*", "")
End If

RetMatch = RetMatch & Mid$(FirstString, lngMatchAt1 + 1, lngLocalLongestMatch)

lngLongestMatch = lngLongestMatch _
+ Similarity_sub(lngMatchAt1 + lngLocalLongestMatch, end1, _
lngMatchAt2 + lngLocalLongestMatch, end2, _
b1, b2, _
FirstString, _
strRetMatch2, _
min_match, _
recur_level + 1)

If strRetMatch2 <> "" Then
    RetMatch = RetMatch & "*" & strRetMatch2
Else
    RetMatch = RetMatch & IIf(recur_level = 0 _
    And lngLocalLongestMatch > 0 _
    And ((lngMatchAt1 + lngLocalLongestMatch < end1) _
    Or (lngMatchAt2 + lngLocalLongestMatch < end2)) _
    , "*", "")
End If

Similarity_sub = lngLongestMatch

End Function
1
Advertisement
1
1
2015-10-30 10:56:53 +0000
Advertisement

このコードは、列aと列bをスキャンし、両方の列に類似性があれば黄色で表示されます。最終的な値を得るためにカラーフィルタを使用することができます。この部分はコードには追加していません。

Sub item_difference()

Range("A1").Select

last_row_all = Range("A65536").End(xlUp).Row
last_row_new = Range("B65536").End(xlUp).Row

Range("A1:B" & last_row_new).Select
With Selection.Interior
    .Pattern = xlSolid
    .PatternColorIndex = xlAutomatic
    .Color = 65535
    .TintAndShade = 0
    .PatternTintAndShade = 0
End With

For i = 1 To last_row_new
For j = 1 To last_row_all

If Range("A" & i).Value = Range("A" & j).Value Then

Range("A" & i & ":B" & i).Select
With Selection.Interior
    .Pattern = xlSolid
    .PatternColorIndex = xlAutomatic
    .ThemeColor = xlThemeColorDark1
    .TintAndShade = 0
  .PatternTintAndShade = 0
End With

End If
Next j
Next i
End Sub
1
1
1
2016-09-14 12:14:05 +0000

私の解決策では、非常に異なる文字列を識別することはできませんが、部分一致(部分一致)には便利です。

**テーブルの中で探す文字列の前後に"*“を追加してください。

  • vlookup(A1,B1:B10,1,0)
  • cerca.vert(A1;B1:B10;1;0)

becomes

  • vlookup(”*“ & A1 & ”*“,B1:B10;1,0)
  • cerca. vert(”*“ & A1 & ”*“;B1:B10;1;0)

”&“はconcatenate()の "ショートバージョン "です。

1
Advertisement
1
1
2015-02-05 02:42:16 +0000
Advertisement

類似度関数(pwrSIMILARITY)を使って、文字列を比較してパーセンテージマッチを得ることができます。大文字小文字を区別することもできますし、区別しないこともできます。どのくらいの割合で一致するかは、必要に応じて決める必要があります。

http://officepowerups.com/help-support/excel-function-reference/excel-text-analyzer/pwrsimilarity/ に参考ページがあります。

しかし、A列のテキストとB列のテキストを比較するのにはかなり有効です。

Advertisement

関連する質問

6
13
9
10
5
Advertisement