Managing inconsistent Excel data and manually identifying near-duplicate records is a notoriously tedious, error-prone struggle for analysts. While enterprise software procurement budgets-the traditional funding sources for dedicated data-cleansing tools-are often restricted, professionals must leverage existing spreadsheet utilities. Fortunately, custom VBA-based fuzzy matching grants users the power to calculate string similarity directly within their workbooks. It is important to note the stipulation that this method requires enabling macros and may impact performance on larger datasets. For example, it easily matches "Acme Corp" with "Acme Corporation." Below, we outline the step-by-step VBA code and formula integration.
Excel is an incredibly powerful tool for data analysis, but it often falls short when dealing with real-world, messy data. Standard search functions like VLOOKUP, MATCH, and XLOOKUP operate on strict exact-match logic. Even with wildcard characters, these native functions fail when confronted with minor typos, missing spaces, transposition errors, or varied spelling conventions (such as "Apple Corp" vs. "Apple Corporation").
While Microsoft provides a standalone "Fuzzy Lookup" Add-In, it lacks flexibility because it cannot be called directly inside an Excel formula. It requires manual execution and is not dynamic. To bridge this gap, we can build a custom User Defined Function (UDF) using VBA (Visual Basic for Applications). This approach allows you to perform fuzzy matching dynamically, directly inside your cells, using a custom formula.
To perform a fuzzy match, we need a mathematical way to measure how similar two text strings are. One of the most robust and widely used algorithms for this is the Levenshtein Distance (also known as Edit Distance).
The Levenshtein Distance calculates the minimum number of single-character edits required to change one word into another. These edits include:
By determining the Levenshtein Distance between two strings, we can calculate a similarity percentage. For example, if two strings require zero edits, they are a 100% match. If they require substantial changes relative to their overall length, their similarity score drops close to 0%.
Below is the complete VBA code required to build a custom fuzzy matching engine in Excel. It consists of two parts:
Levenshtein) that calculates the edit distance and returns a similarity percentage.FuzzyVLookup) that mimics the native VLOOKUP but returns the closest match based on your specified similarity threshold.' Calculates the edit distance between two strings
Function LevenshteinDistance(ByVal s1 As String, ByVal s2 As String) As Long
Dim i As Long, j As Long
Dim len1 As Long, len2 As Long
Dim matrix() As Long
Dim cost As Long
len1 = Len(s1)
len2 = Len(s2)
' Handle empty string edge cases
If len1 = 0 Then
LevenshteinDistance = len2
Exit Function
End If
If len2 = 0 Then
LevenshteinDistance = len1
Exit Function
End If
ReDim matrix(0 To len1, 0 To len2)
' Initialize matrix coordinates
For i = 0 To len1: matrix(i, 0) = i: Next i
For j = 0 To len2: matrix(0, j) = j: Next j
' Fill the matrix
For i = 1 To len1
For j = 1 To len2
If Mid(s1, i, 1) = Mid(s2, j, 1) Then
cost = 0
Else
cost = 1
End If
matrix(i, j) = Application.WorksheetFunction.Min( _
matrix(i - 1, j) + 1, _
matrix(i, j - 1) + 1, _
matrix(i - 1, j - 1) + cost _
)
Next j
Next i
LevenshteinDistance = matrix(len1, len2)
End Function
' Custom User Defined Function for Fuzzy VLookup
Function FuzzyVLookup(ByVal lookup_value As String, _
ByRef table_array As Range, _
ByVal col_index_num As Long, _
Optional ByVal min_similarity_percent As Double = 0.6) As Variant
Dim cell As Range
Dim current_similarity As Double
Dim max_similarity As Double
Dim best_match_row As Range
Dim lookup_len As Long, cell_len As Long, max_len As Long
Dim edit_dist As Long
' Clean input
lookup_value = Trim(LCase(lookup_value))
max_similarity = 0
' Loop through the first column of the lookup range
For Each cell In table_array.Columns(1).Cells
Dim cell_val As String
cell_val = Trim(LCase(cell.Value))
If cell_val <> "" Then
' Calculate Levenshtein Distance
edit_dist = LevenshteinDistance(lookup_value, cell_val)
' Determine maximum possible length for percentage base
lookup_len = Len(lookup_value)
cell_len = Len(cell_val)
If lookup_len > cell_len Then max_len = lookup_len Else max_len = cell_len
' Convert edit distance to a similarity percentage
If max_len > 0 Then
current_similarity = 1 - (edit_dist / max_len)
Else
current_similarity = 0
End If
' Check if this is the best match found so far
If current_similarity > max_similarity And current_similarity >= min_similarity_percent Then
max_similarity = current_similarity
Set best_match_row = cell
End If
End If
Next cell
' Return the corresponding value from the indexed column if a match meets the threshold
If Not best_match_row Is Nothing Then
FuzzyVLookup = best_match_row.Offset(0, col_index_num - 1).Value
Else
' Return #N/A error if no match meets the criteria
FuzzyVLookup = CVErr(xlErrNA)
End If
End Function
To implement this formula in your spreadsheet, follow these quick steps:
ALT + F11 to open the Visual Basic for Applications (VBA) editor.Now that your UDF is installed, you can use it exactly like any standard Excel formula. The syntax for the formula is:
=FuzzyVLookup(lookup_value, table_array, col_index_num, [min_similarity_percent])
lookup_value: The misspelled or variable string you want to search for.table_array: The data range where you want to search. Just like VLOOKUP, the first column of this range will be scanned.col_index_num: The column number in the table range from which to retrieve the value.[min_similarity_percent]: (Optional) A decimal number between 0 and 1 representing the minimum acceptable match confidence. For example, 0.7 means 70% similarity. If omitted, the formula defaults to 0.6 (60%).Imagine you have a client database on Sheet2 in columns A to B:
| Column A (Client Name) | Column B (Contact Email) |
|---|---|
| Microsoft Corp | billing@microsoft.com |
| Apple Inc. | support@apple.com |
| Google LLC | admin@google.com |
On Sheet1, you have a poorly typed lookup list. In cell A2, you have the text "Appel Inc". To retrieve the correct email, you write the following formula in B2:
=FuzzyVLookup(A2, Sheet2!A:B, 2, 0.7)
The formula evaluates "Appel Inc" against "Apple Inc." and calculates a similarity score above 80%. It correctly returns support@apple.com, bypassing the typo completely.
While UDF-based fuzzy matching is incredibly useful, it is resource-intensive. Native Excel functions are highly optimized, whereas VBA loops must evaluate strings character-by-character. If you apply FuzzyVLookup across tens of thousands of rows, you will likely experience performance lag.
To ensure your worksheets remain fast and responsive, implement the following best practices:
A:B), define a specific range (e.g., $A$1:$B$500). This prevents Excel from looping through millions of empty rows.Paste Special > Values). This stops Excel from recalculating the heavy string-matching algorithms every time you edit a cell.Adding fuzzy matching to your Excel toolbelt with VBA changes how you clean and reconcile databases. Instead of spending hours manually resolving typographical discrepancies, this automated, cell-based approach handles inconsistencies seamlessly. By implementing the Levenshtein Distance via a custom FuzzyVLookup formula, you gain structural flexibility while keeping your worksheets dynamic and intelligent.
Disclaimer:
The documents and templates provided on this page are for informational and illustrative purposes only. They do not constitute professional, legal, or financial advice, and should not be relied upon as such. Because individual circumstances and regulatory requirements vary, these materials may not be suitable for your specific needs. We recommend consulting with a qualified professional before adapting or using any of these examples for official or commercial purposes.