首页 > 解决方案 > VBA - 在字符串中查找名称的完全匹配

问题描述

我正在尝试创建这个工具,通过查看费用列表,能够计算欠每个员工的金额。因此,从我们的帐户软件中,我可以导出一个包含 2 列的 excel 文档。第一列有金额,第二列有以下字符串:

“午餐,花费Tanne”

“火车票,花费安妮”

“午餐,支出丹尼斯”

“午餐,花费安妮”

然后,excel 文档将查看所有费用并计算欠每个人的总金额。到目前为止,我已经使用以下代码来计算总金额(一些变量是之前计算的,这只是计算总金额的部分):

'Calcualte total amount
   For i = 1 To NamesTotal
       TotalAmount = 0
       NameString = UCase(Cells(i + 1, 7))
       For j = 1 To EntriesTotal
           CellText = UCase(Cells(j + 2, 3))
               If InStr(1, CellText, NameString) Then
                   Amount = Cells(j + 2, 4)
                   TotalAmount = TotalAmount + Amount         
               End If
           End If
       Next

       Cells(TableStart + i, 3) = Cells(i + 1, 7)
       Cells(TableStart + i, 4) = TotalAmount
       Cells(TableStart + i, 4).NumberFormat = "#,##0.00"
    Next

名称列表列在第 7 列中,字符串列在第 3 列中,数量列在第 4 列中。列表工作正常(我有更多代码)但问题在于名称彼此非常相似

If InStr(1, CellText, NameString) Then

在我上面的示例中,名称“Anne”是名称“Tanne”的一部分,因此 Tanne 的列表也将包括 Anne 的费用。那么如何更改代码以便找到完全匹配的代码呢?

标签: excelvbastring

解决方案


您可以编写一个正则表达式函数,使用单词边界语法将名称作为单词查找,即 \bName\b

在我的示例中,函数的参数等于CellText, NameString

在这里试试。

Option Explicit

Public Sub TEST()
    Dim rng As Range
    For Each rng In [A1:A4]
       If IsNamePresent(rng.Value, "Anne") Then
           'do something
       End If
    Next
End Sub

Public Function IsNamePresent(ByVal inputString As String, testName As String)
    IsNamePresent = False
    With CreateObject("vbscript.regexp")
        .Global = True
        .MultiLine = True
        .IgnoreCase = False '<== You may want to change this
        .Pattern = "\b" & testName & "\b"
        If .TEST(inputString) Then IsNamePresent = True
    End With
End Function

测试值:

在此处输入图像描述


正则表达式:

\b安妮\b / gm

\b在单词边界断言位置(^\w|\w$|\W\w|\w\W)

Anne从字面上匹配字符Anne(区分大小写)

\b在单词边界处断言位置(^\w|\w$|\W\w|\w\W)

因此,必须Anne 作为一个词,而不是Anne作为较长字符串的一部分。


推荐阅读