2016-08-05 37 views
0

Ich habe Adressen in U und V. Ich möchte sehen, ob sie etwas ähnlich sind und wenn sie sagen "Update" Wenn nicht sagen "Auslassen". B. 246 N High street in U und 246 North High St in V würde einen Wert von Update zurückgeben. 246 N High Street in U und 458 Auburn Drive in V würde einen Wert von Omit zurückgeben.Vergleichen von zwei Adressspalten

Irgendwelche Ideen?

+1

Dies ist ein schwieriges Problem im Allgemeinen. Sie müssen eine Art Fuzzy-Matching verwenden. Sehen Sie sich die Antworten [hier] (http://StackOverflow.com/questions/14821345/excel-approximate-text-match) an, um zu erfahren, wie das geht. –

Antwort

0

Es gibt viele Algorithmen für die Fuzzy-Anpassung. Einer der leichteren in Excel zu implementieren ist N-Gram.

Um eine N-Gramm-Übereinstimmung durchzuführen, müssen wir jede Adresse in eine Liste von Sätzen mit kleineren Zeichenlängen aufteilen. Eine 2-Gramm-Liste Ihrer Adresse 246 N High street würde wie 24,46,6 , N,N , H,Hi,ig,gh,h , s,st,tr,re,ee,et aussehen. Wir könnten das gleiche mit einem 3-Gramm: 246,46 ,6 N, N ,N H, Hi,Hig,igh,gh ,h s, st,str,tre,ree,eet

Wir machen dies mit beiden Adressen, dann können wir jedes Element in der ersten Adresse der Liste überprüfen, ob es in der zweiten Adresse Liste erscheint; Zählen Sie die Übereinstimmungen und teilen Sie diese durch die Anzahl der Elemente in der ersten Liste. Das gibt Ihnen einen Prozentsatz davon, wie nahe sie sind.

Sie könnten mit Zellformeln mid() und countif() Phantasie, dies mit Blatt Formeln zu tun, aber ich denke, es ist einfacher zu schreiben es einfach in VBA und machen es zu einem UDF.

Function NGramCompare(string1 As String, string2 As String, intGram As Integer) As Double 
    'Take in two strings and the N-gram 
    Dim intChar As Integer, intGramMatch As Integer 
    Dim ngramList1 As String, ngramList2 As String, nGram As Variant 
    Dim nGramArr1 As Variant 

    'split the first string into a list of ngrams   
    For intChar = 1 To Len(string1) - (intGram-1) 
     If ngramList1 <> "" Then ngramList1 = ngramList1 & "," 
     ngramList1 = ngramList1 & Mid(string1, intChar, intGram) 
    Next intChar 

    'split the secong string into a list of ngrams   
    For intChar = 1 To Len(string2) - (intGram-1) 
     If ngramList2 <> "" Then ngramList2 = ngramList2 & "," 
     ngramList2 = ngramList2 & Mid(string2, intChar, intGram) 
    Next intChar 

    'Split the ngramlist1 into an array through which we can iterate 
    nGramArr1 = Split(ngramList1, ",") 

    'Iterate through array and compare values to ngramlist2 
    For Each nGram In nGramArr1 
     If InStr(1, ngramList2, nGram) Then 
      'we found a match, add to the counter 
      intGramMatch = intGramMatch + 1 
     End If 
    Next nGram 

    'output the percentage of grams matching. 
    NGramCompare = intGramMatch/(UBound(nGramArr1) + 1) 
End Function 

Wenn Sie noch nie ein UDF verwendet haben:

  1. Zum grundlegenden visuellen Editor (VBE) mit Alt + F11
  2. im Fenster VBA-Projekt, Ihre Arbeitsmappe finden und klicken Sie rechts auf der Name
  3. wählen: einfügen >> Modul
  4. Doppel das neue Modul in der Liste klicken, um es dem Codefenster
  5. Fügen sie diese Funktion in zu bringen und Speichern Sie Ihre Arbeitsmappe

Dann address1 Annahme, daß in A1 und address2 ist in B1 können Sie setzen, in C1:

=NGramCompare(A1, B1, 2) 

Welche, für Ihre erste Adresse, ausspucken 56%. Was scheint eine ziemlich gute Übereinstimmung zu sein. Wenn Sie feststellen, dass Sie zu viele positive Treffer erhalten, können Sie Ihre 2-Gramm-Anzeige ändern, indem Sie diesen letzten Parameter ändern.

es einen Schritt weiter zu nehmen, so wird es „Update“ oder „auslassen“ Sie tun könnten sagen:

=If(NGramCompare(A1, B1, 2)>.30, "Update", "Omit") 

ich, dass gerade so eingestellt, dass es eine Übereinstimmung etwas über 30% halten, aber Sie kann nach Bedarf anpassen. Unabhängig davon, wo Sie es festgelegt haben, werden Sie wahrscheinlich einen Prozentsatz von Vergleichen erhalten, die falsch-positiv oder falsch-negativ sind, aber so geht die Fuzzy-Anpassung.

+0

Das ist toll, danke! – Ryan

+0

wow das ist erstaunlich, ich habe es einfach gesagt und und es hat so schnell gearbeitet! Vielen Dank!! – Ryan

+0

Sicher Sache. Ich bin in der Vergangenheit ein paar Mal auf dieses Problem gestoßen, aber es fehlte das Wissen, um es bis vor kurzem zu lösen. Ich bin überrascht, dass es im Internet keine ähnlichen Funktionen gibt, aber ich habe noch nie eine solche gesehen. – JNevill

0

können Einige der naiven Ansätze sein, die ersten paar Zeichen

=LEFT(A1,5)=LEFT(B1,5) 

oder zu ersetzen Teile zu vergleichen, bis sie wahrscheinlich

=(SUBSTITUTE(SUBSTITUTE(LOWER(A2)," street"," ST")," north "," N ") 
=SUBSTITUTE(SUBSTITUTE(LOWER(B2)," street"," ST")," north "," N ")) 

beide passen in eine große hässliche Formel drehen wird nach Anpassung In den meisten Fällen

+0

That = Left wird großartig funktionieren, ich kann mir die ersten paar Ziffern ansehen, um zu sehen, ob sie übereinstimmen. Vielen Dank – Ryan

+0

dann alles vor dem ersten Leerzeichen zu bekommen '= LINKS (A1, FIND (" ", A1) - 1)' – Slai