4

好的,我一直在尝试为此找到解决方案,但我似乎无法做到。我什至无法正确分解问题。这就是想法。

我有两张多行的表(一张有 800 行,另一张有 300,000 行)。每行包含一个名称列,然后是几个包含有关此名称的信息的列。每张表都有不同种类的信息。

我想将这两个工作表合并到一个基于它们都有的 Name 列的主工作表中,因此合并功能非常适合。现在的问题是名称不完全匹配。

例如 Sheet1 包含

“公司 BV”、“信息 #1”
“公司总数”、“信息 #2”
“公司有限公司”、“信息 #3”

第 2 页包含

“公司和公司”、“信息 #4”
“公司和公司”、“信息 #5”

表 1 包含将要使用的所有名称(大约 100,但如上所述以不同的形式),表 2 包含多行中的所有这些 100 以及不在 100 列表中的名称,因此我不关心。

我将如何制作一个 VBA 代码项目,最终结果将是这样的,主表:

“公司”、“信息#1”、“信息#2”、“信息#3”、“信息#4”、“信息#5”

对于那里的每一个“公司”(100 名单)?

我确实希望有一个解决方案。我对 VBA 项目还很陌生,但我以前做过一些最小的编码。

4

5 回答 5

4

我会将宏放在您的个人部分,这样宏在所有工作表中都可用。通过录制一个虚拟宏并选择将其存储在个人宏工作簿中来做到这一点。现在您可以在此个人工作簿中手动添加新的宏和功能。

我刚试过这个(不知道原始来源),效果很好。

公式如下所示: =PERSONAL.XLSB!FuzzyFind(A1,B$1:B$20)

代码在这里:

Function FuzzyFind(lookup_value As String, tbl_array As Range) As String
Dim i As Integer, str As String, Value As String
Dim a As Integer, b As Integer, cell As Variant
For Each cell In tbl_array
  str = cell
  For i = 1 To Len(lookup_value)
    If InStr(cell, Mid(lookup_value, i, 1)) > 0 Then
      a = a + 1
      cell = Mid(cell, 1, InStr(cell, Mid(lookup_value, i, 1)) - 1) & Mid(cell, InStr(cell, Mid(lookup_value, i, 1)) + 1, 9999)
    End If
  Next i
  a = a - Len(cell)
  If a > b Then
    b = a
    Value = str
  End If
  a = 0
Next cell
FuzzyFind = Value
End Function
于 2012-11-12T18:46:52.177 回答
3

您可以 Google Excel UDF 模糊查找或 Levensthein 距离。有一些 UDF 浮动,微软也有一个模糊查找/匹配插件(当我使用它时,它很容易崩溃并且不直观)。

于 2012-11-09T06:25:45.127 回答
3

我使用了罗伯特解决方案,它对我来说很好。我正在为那些不熟悉 excel 但知道编码的人发布完整的解决方案:

虽然这个线程很旧,但我从另一个线程中获取了一些代码并尝试过,看起来解决方案给出了近似匹配。在这里,我试图将 sheet1 的一列与 sheet2 的一列匹配:

  1. 在excel中添加命令按钮
  2. 输入以下代码并单击/运行按钮和函数为您提供选定列的结果
 Private Sub CommandButton21_Click()
     Dim ws As Worksheet
     Dim LRow As Long, i As Long, lval As String


   '~~> Change this to the relevant worsheet
    Set ws = ThisWorkbook.Sheets("Sheet1")

With ws
    '~~> Find Last Row in Col G which has data
    LRow = .Range("D" & .Rows.Count).End(xlUp).Row

    If LRow = 1 Then
        MsgBox "No data in column D"
    Else
        For i = 2 To LRow


             lval = "D"
            .Range("G" & i).Value = FuzzyFind(lval & i, .Range("PWC"))
        Next i
    End If
    End With

    End Sub


    Function FuzzyFind(lookup_value As String, tbl_array As Range) As String
    Dim i As Integer, str As String, Value As String
    Dim a As Integer, b As Integer, cell As Variant

    For Each cell In tbl_array
     str = cell
     For i = 1 To Len(lookup_value)
      If InStr(cell, Mid(lookup_value, i, 1)) > 0 Then
     a = a + 1
     cell = Mid(cell, 1, InStr(cell, Mid(lookup_value, i, 1)) - 1) & Mid   (cell, InStr(cell, Mid(lookup_value, i, 1)) + 1, 9999)
    End If
     Next i
     a = a - Len(cell)
     If a > b Then
       b = a
       Value = str
    End If
       a = 0
    Next cell
      If Value <> "" Then
         FuzzyFind = Value
      Else
         FuzzyFind = "None"
      End If
End Function
于 2015-11-24T12:39:12.697 回答
0

看看这个 DDoE 帖子上的功能。您可以生成一个最长的公共序列字符串并将其长度与原始字符串进行比较。给它一些已知的匹配和一些接近的不匹配,看看你是否能看到它们之间的清晰分界线。

这些函数用于比较,而不是查找紧密匹配,但它们可能对您有用。

于 2012-11-08T22:24:08.603 回答
0

不完全正确但类似,处理我的问题的人可能会在搜索时找到页面。

任务:一份曾遭遇车祸的患者名单,包括街道地址。根据相同的街道地址查找相关帐户。该列表最多可能有 120 条记录——因此部分人工审查是现实的。

问题:街道地址相似但不相同,例如 123 JONES LANE 和 123 JONES LN 或 72 MAIN STREET #32 和 72 MAIN STREET #32。

部分解决方案是仅比较街道号码。对于这样大小的列表,具有相同街道编号的两个不同地址是不常见的(例如,123 JONES LANE 和 123 MAIN STREET)。

注意:您不能使用 VAL() 来提取街道号码。试试 167 E 13 ST。VBA 将其视为 167^13,如果您将 Street_Num 作为整数输出,则会崩溃。因此,您必须使用循环将数字拉入新字符串并在第一个非数字字符处停止。

于 2018-04-05T21:44:38.487 回答