Fuzzy match vba excel

Fuzzy text matching is very useful when you want to compare a text string against other strings that don’t have to be identical. You still, however, want to find the one that is closest in terms of words. Fuzzy matching is very useful when e.g. you want to compare a user question against a database of solutions/answers. That is basically what Google does everyday. Rarely will your question ideally match the title of a blog or news article so Google tries to rank pages using fuzzy matching to find ones that are closest to your query.

Microsoft Fuzzy Lookup AddIn

As Fuzzy matching / lookup is a frequent feature Excel users required Microsoft decide to create their own Fuzzy Lookup AddIn. The AddIn basically allows you to lookup columns from another table using Fuzzy Matching and copy them to your source table.

Go here to find Microsoft Official Fuzzy Lookup AddIn for Excel

When playing with the Fuzzy Lookup AddIn I wasn’t happy with it. I had an enormous database of user Questions and Answers and I wanted to have a choice of which items it will match for each of my records basis the user query. Often the fuzzy match algorithm would suggest a match that wasn’t perfect given context. Hence I decide to create my own Fuzzy Match VBA UserForm….

Custom Fuzzy Match using VBA UserForm

What I wanted was an easy way to lookup my query against a Knowledge Base of questions that are ranked in terms of their match against the query. The closer the query is to the question the higher the match. That way I can decide whether indeed I want to take the answer from the question with the highest match rate or maybe one of the below. The additional requirement was to ignore so called “stop words” in my query (the, a, it etc.) as these could generate a lot of false matches, while I wanted fuzzy matching only focus on the keywords.
Example Fuzzy Match
To show you how the Fuzzy Match VBA UserForm works I created a simple Knowledge Base of Excel/VBA related questions. The KB consists of 3 basis columns: Questions, Answer and Category. The Category column is especially useful as looking at the query you might want to limit the Fuzzy algorithm to run on only a subset of items in your database.

Example Knowledge Base of Questions and Answers

An example Knowledge Base

Designing the Fuzzy Match UserForm

Below a quick overview of the Fuzzy Match VBA UserForm if you want to see it in action:

Below you can find the design of the VBA Fuzzy Match UserForm.

Fuzzy Match UserForm

The design of the VBA Fuzzy Match UserForm

Each field is explained below:

  • Text Selected – text from the Excel cell you selected in your workbook before running the VBA macro
  • Search Question – if you want to override the “Text Selected” field simply type your query here and hit the Search button again. A typical scenario for this field is when you see that the result for your “Text Selected” don’t return satisfactory results and you would like to adjust the query
  • Category(s) – if you want to improve the algorithm performance or simply reduce the categories to be searched then select the ones you are interested in
  • Search – the Search button will run the algorithm and return results to the “Results” table
  • Selected Question / Selected Answer – when you click on one of the results these fields will show the full text of the Question and Answer column. This makes it easier to copy the results where needed

The VBA Code

Initializing the UserForm

Firstly we will initialize our UserForm and assure it is showing us the current list of categories in our “KnowledgeBase” worksheet:

Private Sub UserForm_Initialize()
    Set catDict = GetListofCategories()
    For Each it In catDict.keys
        lbCategory.AddItem it
    Next it
    lbCategory.AddItem "Any"
    For i = 0 To lbCategory.ListCount - 1
        lbCategory.Selected(i) = True
    Next i
    tbSelectedQuestion.Text = Selection.Value
End Sub

Function GetListofCategories()
    Dim question As Range
    Set dict = CreateObject("Scripting.Dictionary")
    Set wsQnA = GetQnAWorksheet
    For Each question In wsQnA.Range("C:C").SpecialCells(xlCellTypeConstants)
        If question.Row > 1 Then
            If Not dict.Exists(question.Value) Then
                dict.Add question.Value, 1
            End If
        End If
    Next question
    Set GetListofCategories = dict
End Function

Function GetQnAWorksheet() As Worksheet
    Dim ws As Worksheet
    For Each ws In ActiveWorkbook.Sheets
        If ws.Name Like "KnowledgeBase*" And ws.Visible Then
            Set GetQnAWorksheet = ws
            Exit Function
        End If
    Next ws
    MsgBox "KnowledgeBase worksheet not found!~", vbCritical + vbOKOnly, "Error"
    Set GetQnAWorksheet = Nothing
End Function

Function for removing Stop Words

Before we focus on generating matches let us focus for a sec on creating a function that will remove stop words from a given sentence. This will help us get rid of all those unnecessary words like “the, it, this” etc. that will dilute the fuzzy algorithm.

Function RemoveStopWords(sentence As String) As Collection
    If IsEmpty(stopWords) Then stopWords = Split("a;about;above;after;again;against;all;am;an;and;any;are;aren't;as;at;be;because;been;before;being;below;between;both;but;by;can't;cannot;chat;could;couldn't;did;didn't;do;does;doesn't;doing;don't;down;during;each;few;for;from;further;had;hadn't;has;hasn't;have;haven't;having;he;he'd;he'll;he's;her;here;here's;hers;herself;hi;him;himself;his;how;how's;i;i'd;i'll;i'm;i've;if;in;into;is;isn't;it;it's;its;itself;let's;me;more;most;mustn't;my;myself;need;needs;no;nor;not;of;off;on;once;only;or;other;ought;our;ours;out;over;own;same;shan't;she;she'd;she'll;she's;should;shouldn't;so;some;such;than;that;that's;the;their;theirs;them;themselves;then;there;there's;these;they;they'd;they'll;they're;they've;this;those;through;to;too;under;until;up;very;was;wasn't;we;we'd;we'll;we're;we've;were;weren't;what;what's;when;when's;where;where's;which;while;who;who's;whom;why;why's;with;won't;would;wouldn't;you;you'd;you'll;you're;you've;your;yours;yourself;yourselves;?;!;" & _
             "-;,;", ";")
    Dim stopR As Range, r As Variant, col As Collection
    Set col = New Collection
    For Each w In Split(sentence, " ")
        If Not (IsNumeric(Trim(w))) Then
            w = Trim(w)
            If Len(w) > 0 Then col.Add w
        End If
    Next w
    For Each r In stopWords
        For i = col.Count To 1 Step -1
            If UCase(col(i)) = UCase(r) Then
                col.Remove i
            End If
        Next i
    Next r
    Set RemoveStopWords = col
End Function

You probably noticed I embedded a lot of words directly in the function. This makes it easy to add or remove stop words quickly.

Fuzzy Matching algorithm

Now for the meaty part :). Below the key logic for generating the results:

Public stopWords As Variant
Dim selectedChat As Range
Private Sub cbSearch_Click()
    'Clear Search worksheet
    Set selectedChat = Selection
    Dim wsRes As Worksheet: Set wsRes = GetSearchWorksheet
    selectedChat.Worksheet.Activate
    'Remove stop words from question
    Dim qCol As Collection
    Set qCol = RemoveStopWords(Selection.Value)
    'Search
    Dim wsQnA As Worksheet, r As Range, saCol As Collection, sa() As String, saIndex As Long
    Dim dict As Object, dstR As Range, startCount As Long, pMax As Long, currProgress As Long
    Set dict = CreateObject("Scripting.Dictionary")
    For i = 0 To lbCategory.ListCount - 1
        If lbCategory.Selected(i) Then
            dict.Add lbCategory.List(i), lbCategory.List(i)
        End If
    Next i
    'Search question matching Service Area, search query and calculate match
    Set wsQnA = GetQnAWorksheet
    If wsQnA Is Nothing Then Exit Sub
    startCount = wsRes.Range("A:A").SpecialCells(xlCellTypeConstants).Count
    pMax = wsQnA.Range("A:A").SpecialCells(xlCellTypeConstants).Count
    For Each r In wsQnA.Range("A:A").SpecialCells(xlCellTypeConstants)
        If dict.Exists(r.Offset(0, 4).Value) Or IsEmpty(r.Offset(0, 4).Value) And r.Row > 1 Then
            If tbSearch.Value = vbNullString Or InStr(1, r.Value, tbSearch.Value, vbTextCompare) > 0 Then
                Set dstR = wsRes.Range("A1").Offset(startCount):  startCount = startCount + 1
                dstR.Value = r.Value
                dstR.Offset(0, 1).Value = r.Offset(0, 1).Value
                dstR.Offset(0, 2).Value = r.Offset(0, 2).Value
                dstR.Offset(0, 3).Value = CalculateMatch(qCol, r.Value)
                dstR.Offset(0, 3).NumberFormat = "0%"
            End If
        End If
        currProgress = currProgress + 1
        If currProgress Mod 100 = 0 Then
            lStatus.Caption = "Searching " & Format(CDbl(currProgress) / pMax, "0%")
            DoEvents
        End If
    Next r
    'Display Search sorted by Match
    If wsRes.UsedRange.Rows.Count > 0 Then
        With wsRes.Sort
            .SortFields.Clear
            .SortFields.Add2 Key:=GetSearchLastColumn(wsRes), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
            .SetRange wsRes.UsedRange
            .Header = xlYes
            .MatchCase = False
            .Orientation = xlTopToBottom
            .SortMethod = xlPinYin
            .Apply
        End With
    End If
    
    lbResult.RowSource = GetSearchRangeAddress(wsRes)
    lStatus.Caption = "" & lbResult.ListCount & " Questions found"
End Sub
Function GetSearchRangeAddress(ws As Worksheet)
    GetSearchRangeAddress = "'" & ws.Name & "'!" & Range(ws.Range("A2"), ws.Cells(ws.UsedRange.Rows.Count, ws.UsedRange.Columns.Count)).AddressLocal
End Function
Function GetSearchLastColumn(ws As Worksheet) As Range
    Set GetSearchLastColumn = Range(ws.Range("D2"), ws.Cells(ws.UsedRange.Rows.Count, ws.UsedRange.Columns.Count))
End Function

Function CalculateMatch(sentCol As Collection, sentence As String) As Double
    Dim m As Long, s() As String
    s = Split(sentence, " ")
    For Each w In sentCol
        For Each ws In s
            If UCase(ws) = UCase(w) Then
                m = m + 1
                Exit For
            End If
        Next ws
    Next w
    CalculateMatch = m / sentCol.Count
End Function
Sub CreateSearchResultsHeader(ws As Worksheet)
    ws.Range("A1").Value = "Questions"
    ws.Range("B1").Value = "Answer"
    ws.Range("C1").Value = "Category"
    ws.Range("D1").Value = "Match"
End Sub
Sub AddSearchResultsRow(ws As Worksheet, rowNum As Long, question As String, answer As String, sa As String, match As String)
    ws.Range("A" & rowNum).Value = question
    ws.Range("B" & rowNum).Value = answer
    ws.Range("C" & rowNum).Value = sa
    ws.Range("D" & rowNum).Value = match
End Sub
Function GetSearchWorksheet()
    Dim ws As Worksheet
    For Each ws In ActiveWorkbook.Sheets
        If ws.Name = "SearchResults" Then
            ws.UsedRange.Clear
            CreateSearchResultsHeader ws
            Set GetSearchWorksheet = ws
            Exit Function
        End If
    Next ws
    Set ws = ActiveWorkbook.Sheets.Add
    ws.Name = "SearchResults"
    CreateSearchResultsHeader ws
    Set GetSearchWorksheet = ws
End Function

The above code will do the following – compare the query to each question from the selected categories, calculate the match and add it to a temporary worksheet. Once done the table in the form will be connected to the range in the temporary worksheet and displayed.

Below a few other pieces of code that help display the Q/A in the text boxes and help us clean-up:

Private Sub lbResult_Click()
    'Display question and answer in textbox below
    For i = 0 To lbResult.ListCount - 1
        If lbResult.Selected(i) Then
            tbQ.Value = lbResult.List(i, 0)
            tbA.Value = lbResult.List(i, 1)
        End If
    Next i
End Sub

Private Sub UserForm_Terminate()
    On Error Resume Next
    Application.DisplayAlerts = False
    ActiveWorkbook.Sheets("SearchResults").Delete
    Application.DisplayAlerts = True
End Sub

Download the entire VBA Code Module

If you want to download the entire VBA Code Module for the Excel VBA Fuzzy Match UserForm click the download button below:
Download

Одна из самых неприятных ситуаций, с которой может столкнуться пользователь при работе в Microsoft Excel — это поиск и подстановка данных с неточным совпадением. Когда вам надо подставить данные из одной таблицы в другую, но вы при этом уверены, что в обеих таблицах совпадающие элементы называются одинаково, то проблем нет — к вашим услугам множество способов: функции ВПР и её аналоги, надстройка Power Query и т.д.

А вот если в одной таблице «Пупкин Василий», а в другой просто «Пупкин», или «Пупкин В.», или даже «Пупкен», то все эти красивые способы не работают. Причем на практике такое встречается постоянно, особенно с почтовыми адресами или названиями компаний:

Неточный поиск адресов

Обратите внимание на различные типы несоответствий, которые могут встречаться:

  • переставлены местами улица, город, дом
  • отсутствует какая-то часть адреса или, наоборот, есть что-то лишнее (индекс, номер квартиры)
  • по-разному записан город (с буквой «г.» или без) или улица
  • опечатки и ошибки (Козань вместо Казань)

Про точное соответствие или даже поиск по маске тут говорить не приходится. Помочь в таком случае могут только специальные макросы или надстройки для Excel. Про одну из таких макро-функций на VBA я уже писал, а здесь хочется рассказать про еще один вариант решения подобной задачи — надстройку Fuzzy Lookup от компании Microsoft.

Эта надстройка существует с 2011 года и совершенно бесплатно скачивается с сайта Microsoft. Системные требования: Windows 7 или новее, Office 2007 или новее, соответственно. После установки у вас в Excel появляется одноименная вкладка с единственной кнопкой на ней:

Кнопка надстройки Fuzzy Lookup

Нажатие на эту кнопку включает специальную панель в правой части окна Excel, где и задаются все настройки поиска:

Неточный поиск в Fuzzy Lookup

Сразу хочу отметить, что эта надстройка умеет работать только с умными таблицами, поэтому все исходные таблицы нужно конвертировать в умные с помощью сочетания Ctrl+T или кнопки Форматировать как таблицу на вкладке Главная (Home — Format as Table):

Алгоритм действий при работе с надстройкой Fuzzy Lookup следующий:

  1. Выберите какие таблицы нужно связать в выпадающих списках Left и Right Table.
  2. Выберите ключевые столбцы в левой и правой таблицах, по которым нужно проверить соответствие и нажмите кнопку для добавления созданной пары в список Match Columns
  3. В списке Output Columns отметьте галочками столбцы, которые вы хотите получить на выходе в качестве результата.
  4. Установите активную ячейку в пустое место на листе, куда вы хотите вывести данные
  5. Нажмите кнопку Go

После анализа мы получаем таблицу, где каждому элементу ключевого столбца из первой таблицы подобрано максимально похожее значение из второй:

Результат

Лепота!

Нюансы и подводные камни

  • Точность подбора можно регулировать с помощью ползунка Similarity Threshold в нижней части панели Fuzzy Lookup. Чем правее его положение, тем строже будет поиск, и — как следствие — тем меньше результатов надстройка будет находить. Если сдвинуть его влево, то результатов станет больше, но возрастет риск ошибочного совпадения. Тут все зависит от вашей конкретной ситуации — экспериментируйте.
  • На больших таблицах поиск может занимать приличное количество времени (до нескольких десятков секунд), хотя многое, конечно, зависит от мощности вашего компьютера. Как вариант, для ускорения в настройках (кнопка Configure в нижней части панели) можно попробовать включить параметр UseApproximateIndexing в разделе Global Settings.
  • Перед нажатием на кнопку Go не забудьте выделить пустую ячейку, начиная с которой вы хотите вывести результаты. Если случайно вы оставите активную ячейку где-нибудь в исходных данных, то надстройка выведет итоговую таблицу прямо поверх них, и вы их потеряете. Причем отмена последнего действия будет невозможна, а кнопка Undo в нижней части панели не всегда срабатывает почему-то.
  • Для вывода столбца с коэффициентом подобия FuzzyLookup.Similarity необходимо, чтобы у вашего Excel была точка в качестве десятичного разделителя (целой и дробной части). Если это не так, то эту настройку временно можно поменять через Файл — Параметры — Дополнительно (File — Options — Advanced).
  • Fuzzy Lookup — это не обычная надстройка, написанная на VBA (как мой PLEX, например), а COM-надстройка. Разница в том, что она устанавливается как отдельная программа, т.е. вам нужны соответствующие права на установку ПО на вашем компьютере. Дома, ясное дело, проблем не будет, а вот многим корпоративным пользователям, скорее всего, придется обращаться к вашим айтишникам. После установки отключать и подключать ее в дальнейшем можно на вкладке Разработчик — Надстройки COM (Developer — COM Add-ins).

В любом случае, при всех имеющихся минусах, эта надстройка однозначно стоит того, чтобы находиться в арсенале любого продвинутого пользователя Microsoft Excel.

Ссылки по теме

  • Неточный поиск ближайшего похожего текста с помощью макрофункции
  • Анализ текста регулярными выражениями (RegExp) в Excel
  • Ссылка на скачивание надстройки Fuzzy Lookup с сайта Microsoft

Here is a VBA implementation of the Levenshein Distance. You can adjust the threshold to fit your needs.

Public Function Levenshtein(str1 As String, str2 As String) As Integer
On Error GoTo ErrHandler
    Dim arrLev, intLen1 As Integer, intLen2 As Integer, i As Integer
    Dim j, arrStr1, arrStr2, intMini As Integer

    intLen1 = Len(str1)
    ReDim arrStr1(intLen1 + 1)
    intLen2 = Len(str2)

    ReDim arrStr2(intLen2 + 1)
    ReDim arrLev(intLen1 + 1, intLen2 + 1)

    arrLev(0, 0) = 0
    For i = 1 To intLen1
        arrLev(i, 0) = i
        arrStr1(i) = Mid(str1, i, 1)
    Next

    For j = 1 To intLen2
        arrLev(0, j) = j
        arrStr2(j) = Mid(str2, j, 1)
    Next

    For j = 1 To intLen2
        For i = 1 To intLen1
            If arrStr1(i) = arrStr2(j) Then
                arrLev(i, j) = arrLev(i - 1, j - 1)
            Else
                intMini = arrLev(i - 1, j) 'deletion
                If intMini > arrLev(i, j - 1) Then intMini = arrLev(i, j - 1) 'insertion
                If intMini > arrLev(i - 1, j - 1) Then intMini = arrLev(i - 1, j - 1) 'deletion

                arrLev(i, j) = intMini + 1
            End If
        Next
    Next

    Levenshtein = arrLev(intLen1, intLen2)
    Exit Function

ErrHandler:
    MsgBox Err.Description
    Exit Function
End Function

vba_fuzzymatching

Introduction:


This VBA module contains 4 user-defined functions (UDFs) that enable Excel users to execute fuzzy matching by using the basic algorithm for computing the Levenshtein Distance between two strings. Following are details on these functions.

Functions


=LevD([String 1],[String 2])

Calculates the Levenshtein Distance between two strings. The Levenshtein Distance is the minimum number of character insertions, deletions, and substitutions required to perfectly match one string to another. This formula isn’t case sensitive.

=Fuzzy_Match([String 1],[Array of Strings], [Threshold])

Traverses an array of strings, calculating the Levenshtein Distance between each item (string) in the [Array of Strings] and [String 1] (String 1 is the string you are seeking a match for). If a value in the array of strings is a sentence (includes a space), then it will be partitioned and matched based on the best-matching substring (see «bestword» function below). The third paramter: [Threshold], requires an input value between 0 and 1. This is the minimum string similiarity the user desires for fuzzy matching, e.g., if the user inputs «.75», then no matches will be returned with a string similarity less than 75%. This function Returns the closest match, i.e., the string with the lowest Levenshtein Distance.

Note: If two or more strings have lowest Levenshtein distance, the first one traversed in the [Array of Strings] will be returned.

=bestword([string1], [string2])

Takes a sentence ([string2] and partitions it using delimeter = (» «). Then each substring will be matched to [String1]. The best matching substring will be returned.

=String_Similarity([String 1],[String 2])

Calculates the similarity percentage between two strings using the Levenshtein Distance, e.g., «rock» and «sock» are 75% similiar, because 3 of their 4 characters are the same.

Technologies Used


Visual Basic Editor for Excel

References


Levenshtein Distance Formula: https://en.wikipedia.org/wiki/Levenshtein_distance?msclkid=154f886daafe11ec82b22174e1344ccf

Basic string similarity formula: http://adamfortuno.com/index.php/2021/07/05/levenshtein-distance-and-distance-similarity-functions/?msclkid=aa598709a8b611ec8de2ac84df81a9da

Содержание

  1. Нечеткий текстовый поиск с Fuzzy Lookup в Excel
  2. Нюансы и подводные камни
  3. Analyst Cave
  4. Excel VBA Fuzzy Match text against a table
  5. Microsoft Fuzzy Lookup AddIn
  6. Custom Fuzzy Match using VBA UserForm
  7. Designing the Fuzzy Match UserForm
  8. The VBA Code
  9. Initializing the UserForm
  10. Function for removing Stop Words
  11. Fuzzy Matching algorithm
  12. Download the entire VBA Code Module
  13. Matching similar but not exact text strings in Excel VBA projects
  14. 5 Answers 5

Нечеткий текстовый поиск с Fuzzy Lookup в Excel

Одна из самых неприятных ситуаций, с которой может столкнуться пользователь при работе в Microsoft Excel — это поиск и подстановка данных с неточным совпадением. Когда вам надо подставить данные из одной таблицы в другую, но вы при этом уверены, что в обеих таблицах совпадающие элементы называются одинаково, то проблем нет — к вашим услугам множество способов: функции ВПР и её аналоги, надстройка Power Query и т.д.

А вот если в одной таблице «Пупкин Василий», а в другой просто «Пупкин», или «Пупкин В.», или даже «Пупкен», то все эти красивые способы не работают. Причем на практике такое встречается постоянно, особенно с почтовыми адресами или названиями компаний:

Обратите внимание на различные типы несоответствий, которые могут встречаться:

  • переставлены местами улица, город, дом
  • отсутствует какая-то часть адреса или, наоборот, есть что-то лишнее (индекс, номер квартиры)
  • по-разному записан город (с буквой «г.» или без) или улица
  • опечатки и ошибки (Козань вместо Казань)

Про точное соответствие или даже поиск по маске тут говорить не приходится. Помочь в таком случае могут только специальные макросы или надстройки для Excel. Про одну из таких макро-функций на VBA я уже писал, а здесь хочется рассказать про еще один вариант решения подобной задачи — надстройку Fuzzy Lookup от компании Microsoft.

Эта надстройка существует с 2011 года и совершенно бесплатно скачивается с сайта Microsoft. Системные требования: Windows 7 или новее, Office 2007 или новее, соответственно. После установки у вас в Excel появляется одноименная вкладка с единственной кнопкой на ней:

Нажатие на эту кнопку включает специальную панель в правой части окна Excel, где и задаются все настройки поиска:

Сразу хочу отметить, что эта надстройка умеет работать только с умными таблицами, поэтому все исходные таблицы нужно конвертировать в умные с помощью сочетания Ctrl + T или кнопки Форматировать как таблицу на вкладке Главная (Home — Format as Table) :

Алгоритм действий при работе с надстройкой Fuzzy Lookup следующий:

  1. Выберите какие таблицы нужно связать в выпадающих списках Left и Right Table.
  2. Выберите ключевые столбцы в левой и правой таблицах, по которым нужно проверить соответствие и нажмите кнопку для добавления созданной пары в список Match Columns
  3. В списке Output Columns отметьте галочками столбцы, которые вы хотите получить на выходе в качестве результата.
  4. Установите активную ячейку в пустое место на листе, куда вы хотите вывести данные
  5. Нажмите кнопку Go

После анализа мы получаем таблицу, где каждому элементу ключевого столбца из первой таблицы подобрано максимально похожее значение из второй:

Нюансы и подводные камни

  • Точность подбора можно регулировать с помощью ползунка Similarity Threshold в нижней части панели Fuzzy Lookup. Чем правее его положение, тем строже будет поиск, и — как следствие — тем меньше результатов надстройка будет находить. Если сдвинуть его влево, то результатов станет больше, но возрастет риск ошибочного совпадения. Тут все зависит от вашей конкретной ситуации — экспериментируйте.
  • На больших таблицах поиск может занимать приличное количество времени (до нескольких десятков секунд), хотя многое, конечно, зависит от мощности вашего компьютера. Как вариант, для ускорения в настройках (кнопка Configure в нижней части панели) можно попробовать включить параметр UseApproximateIndexing в разделе Global Settings.
  • Перед нажатием на кнопку Goне забудьте выделить пустую ячейку, начиная с которой вы хотите вывести результаты. Если случайно вы оставите активную ячейку где-нибудь в исходных данных, то надстройка выведет итоговую таблицу прямо поверх них, и вы их потеряете. Причем отмена последнего действия будет невозможна, а кнопка Undo в нижней части панели не всегда срабатывает почему-то.
  • Для вывода столбца с коэффициентом подобия FuzzyLookup.Similarity необходимо, чтобы у вашего Excel была точка в качестве десятичного разделителя (целой и дробной части). Если это не так, то эту настройку временно можно поменять через Файл — Параметры — Дополнительно (File — Options — Advanced) .
  • Fuzzy Lookup — это не обычная надстройка, написанная на VBA (как мой PLEX, например), а COM-надстройка. Разница в том, что она устанавливается как отдельная программа, т.е. вам нужны соответствующие права на установку ПО на вашем компьютере. Дома, ясное дело, проблем не будет, а вот многим корпоративным пользователям, скорее всего, придется обращаться к вашим айтишникам. После установки отключать и подключать ее в дальнейшем можно на вкладке Разработчик — Надстройки COM (Developer — COM Add-ins) .

В любом случае, при всех имеющихся минусах, эта надстройка однозначно стоит того, чтобы находиться в арсенале любого продвинутого пользователя Microsoft Excel.

Источник

Analyst Cave

Simply the best place to learn Excel and Analytics

Home » Excel VBA Fuzzy Match text against a table

Excel VBA Fuzzy Match text against a table

Fuzzy text matching is very useful when you want to compare a text string against other strings that don’t have to be identical. You still, however, want to find the one that is closest in terms of words. Fuzzy matching is very useful when e.g. you want to compare a user question against a database of solutions/answers. That is basically what Google does everyday. Rarely will your question ideally match the title of a blog or news article so Google tries to rank pages using fuzzy matching to find ones that are closest to your query.

Microsoft Fuzzy Lookup AddIn

As Fuzzy matching / lookup is a frequent feature Excel users required Microsoft decide to create their own Fuzzy Lookup AddIn. The AddIn basically allows you to lookup columns from another table using Fuzzy Matching and copy them to your source table.

When playing with the Fuzzy Lookup AddIn I wasn’t happy with it. I had an enormous database of user Questions and Answers and I wanted to have a choice of which items it will match for each of my records basis the user query. Often the fuzzy match algorithm would suggest a match that wasn’t perfect given context. Hence I decide to create my own Fuzzy Match VBA UserForm….

Custom Fuzzy Match using VBA UserForm

What I wanted was an easy way to lookup my query against a Knowledge Base of questions that are ranked in terms of their match against the query. The closer the query is to the question the higher the match. That way I can decide whether indeed I want to take the answer from the question with the highest match rate or maybe one of the below. The additional requirement was to ignore so called “stop words” in my query (the, a, it etc.) as these could generate a lot of false matches, while I wanted fuzzy matching only focus on the keywords.

To show you how the Fuzzy Match VBA UserForm works I created a simple Knowledge Base of Excel/VBA related questions. The KB consists of 3 basis columns: Questions, Answer and Category. The Category column is especially useful as looking at the query you might want to limit the Fuzzy algorithm to run on only a subset of items in your database. An example Knowledge Base

Designing the Fuzzy Match UserForm

Below a quick overview of the Fuzzy Match VBA UserForm if you want to see it in action:

Below you can find the design of the VBA Fuzzy Match UserForm.
The design of the VBA Fuzzy Match UserForm
Each field is explained below:

  • Text Selected – text from the Excel cell you selected in your workbook before running the VBA macro
  • Search Question – if you want to override the “Text Selected” field simply type your query here and hit the Search button again. A typical scenario for this field is when you see that the result for your “Text Selected” don’t return satisfactory results and you would like to adjust the query
  • Category(s) – if you want to improve the algorithm performance or simply reduce the categories to be searched then select the ones you are interested in
  • Search – the Search button will run the algorithm and return results to the “Results” table
  • Selected Question / Selected Answer – when you click on one of the results these fields will show the full text of the Question and Answer column. This makes it easier to copy the results where needed

The VBA Code

Initializing the UserForm

Firstly we will initialize our UserForm and assure it is showing us the current list of categories in our “KnowledgeBase” worksheet:

Function for removing Stop Words

Before we focus on generating matches let us focus for a sec on creating a function that will remove stop words from a given sentence. This will help us get rid of all those unnecessary words like “the, it, this” etc. that will dilute the fuzzy algorithm.

You probably noticed I embedded a lot of words directly in the function. This makes it easy to add or remove stop words quickly.

Fuzzy Matching algorithm

Now for the meaty part :). Below the key logic for generating the results:

The above code will do the following – compare the query to each question from the selected categories, calculate the match and add it to a temporary worksheet. Once done the table in the form will be connected to the range in the temporary worksheet and displayed.

Below a few other pieces of code that help display the Q/A in the text boxes and help us clean-up:

Download the entire VBA Code Module

If you want to download the entire VBA Code Module for the Excel VBA Fuzzy Match UserForm click the download button below:
Download

Источник

Matching similar but not exact text strings in Excel VBA projects

Okay, I have been trying to find a solution for this and I just don’t seem to be able. I can’t even break down the problem properly. This is the idea.

I have two sheets with many rows (one with 800 and the other with 300,000). Each row contains a Name column and then several columns that contain information about this Name. Each sheet has different kinds of information.

I want to consolidate these two sheets into a master sheet based on this Name column they both have, so the consolidate function is perfect for this. Now the problem is that the names don’t match perfectly.

For example Sheet1 contains

«Company B.V.», «Info #1»
«Company Total», «Info #2»
«Company Ltd», «Info #3»

and sheet 2 contains

«Company and Co.», «Info #4»
«Company and Co», «Info #5»

Sheet 1 contains all the names that are going to be used (around a 100 but in different forms as stated above) and sheet 2 contains all these 100 in multiple rows plus names that aren’t in the 100 list and therefore I don’t care about.

How would I make a VBA code project where the end result would be something like this, Master sheet:

«Company», «Info #1», «Info #2», «Info #3», «Info #4», «Info #5»

for every single «Company» (the 100 list) in there??

I do hope there is a solution for this. I’m pretty new to VBA projects, but I have done some minimal coding before.

5 Answers 5

I would place the macro in your PERSONAL section, this way the macro is available in all worksheets. Do this by recording a dummy macro and select to store it in Personal Macro workbook. Now you can manually add new macro’s and functions in this personal workbook.

I just tried this one (don’t know the original source) and it works fine.

The formula looks like this: =PERSONAL.XLSB!FuzzyFind(A1,B$1:B$20)

The code is here:

You can Google Excel UDF Fuzzy lookup or Levensthein distance. There are some UDF’s floating around and Microsoft does have a Fuzzy lookup/match add-on as well (when I used it, it was crash prone and not intuitive).

I used Robert solution and it works fine for me. I am posting whole solution for people who are new for excel but knows coding:

Though this thread is old but I took some code from another threads and tried and looks like solution is giving approx match. Here I am trying to match one column of sheet1 with one column of sheet2:

  1. add command button in excel
  2. put following code and click/run button and function gives you result in selected column

Take a look at the functions on this DDoE post. You could generate a longest common sequence string and compare the length to the original string. Feed it some known matches and some close non-matches and see if you can see a clear dividing line between them.

These functions are used for diffing, not finding close matches, but they may work for you.

Not exactly on point but similar, and people dealing with my issue are likely to find this page when searching.

Task: A list of patients who have been in car wrecks, including street addresses. Find related accounts based on same street address. The list will be a maximum of maybe 120 records—so partial manual review is realistic.

Problem: Street addresses are similar but not identical, e.g. 123 JONES LANE and 123 JONES LN or 72 MAIN STREET #32 and 72 MAIN STREET # 32.

Part of the solution is to compare only the street numbers. With a list that size it’s unusual to have two different addresses with the same street number (e.g., 123 JONES LANE and 123 MAIN STREET).

Caution: You can’t use VAL() to pull the street number. Try it with 167 E 13 ST. VBA sees that as 167^13 and will crash if you are outputting to Street_Num As Integer. So you have to use a loop to pull the digits into a new string and stop at the first non-digit character.

Источник

Понравилась статья? Поделить с друзьями:
  • Funny from the word
  • Fuzzy match for excel
  • Funny find a word
  • Funny characters in word
  • Fuzzy lookup excel скачать