Excel - 跨表单查找数据的有效方法

时间:2016-09-04 21:18:26

标签: excel excel-vba excel-formula vba

我目前有一张包含两张工作表的电子表格。第一个工作表是名称和地址列表,第二个是包含姓名和地址以及电子邮件地址的列表(工作表名为“EmailList”)

我正在尝试向第一个工作表中添加一个新列,如果该电子邮件位于第二个工作表中,则会显示该电子邮件地址,方法是匹配firstname,lastname,house number和street address。更好的方法是在新工作表上显示列表,只有整行匹配。

我收到的电子邮件显示使用:

=INDEX(EmailList!P:P, MATCH(A9&B9&C9&E9, EmailList!A:A&EmailList!B:B&EmailList!C:C&EmailList!E:E, 0))

然而它太慢了。第一张纸有1000行,第二张有1500张。

如何从EmailList工作表中轻松选择两个工作表中的名字,姓氏,数字,街道名称列匹配的行?

3 个答案:

答案 0 :(得分:0)

pnuts和Parfait的评论都是很好的建议,值得考虑。

我只是想知道你的结构逻辑是否正确。根据您在问题中所写的内容,而不是找到Sheet1的电子邮件地址,您是否实际从Sheet2中删除了Sheet1上不存在的任何地址?如果是这种情况,那么VBA解决方案将非常简短。如果您从名称,门牌号,地址单元格创建了一个字符串键,则可以填充Collection并在每个Sheet2条目中查找该键。您要开发的一些框架代码如下:

Option Explicit

Sub RunMe()
    Dim data As Variant
    Dim r As Long, c As Long, i As Long
    Dim key As String
    Dim addrs As Collection
    Dim emails As Collection
    Dim hit As Boolean
    Dim vRow As Variant
    Dim output As Variant

    'Read addresses from Sheet1 into collection
    data = Sheet1.UsedRange.Value2
    Set addrs = New Collection
    For r = 1 To UBound(data, 1)
        key = BuildKey(data, r)
        addrs.Add True, key
    Next

    'Interrogate email list
    data = Sheet2.UsedRange.Value2
    Set emails = New Collection
    On Error Resume Next
    For r = 1 To UBound(data, 1)
        key = BuildKey(data, r)
        hit = False
        hit = addrs(key)
        If hit Then emails.Add r
    Next
    On Error GoTo 0

    'Write your results to the new sheet
    ReDim output(1 To emails.Count, 1 To 5)
    i = 1
    For Each vRow In emails
        For c = 1 To 5
            output(i, c) = data(vRow, c)
        Next
        i = i + 1
    Next
    Sheet3.Range("A1").Resize(UBound(output, 1), UBound(output, 2)).Value = output

End Sub
Private Function BuildKey(data As Variant, r As Long) As String
    Dim c As Long

    For c = 1 To 4
        BuildKey = BuildKey & CStr(data(r, c)) & "|"
    Next
End Function

答案 1 :(得分:0)

如上所述,如果使用Excel for PC,请考虑使用SQL。 Excel可以连接到Jet / ACE SQL引擎(Window .dll文件)以在工作表上运行查询,就像它们是数据库表一样。是的,您可以查询运行宏的工作簿,因为您将使用上次保存文件的只读实例。

具体来说,下面的查询在您输出到现有工作表 MainList 和 EmailList 之间运行list >结果:

AvailableBlocks = list() * 128
DirectoryEntries = list() * 64
AvailableBlocks.append(1)
AvailableBlocks.append(2)
print(AvailableBlocks)
DirectoryEntries.append(123)
DirectoryEntries.append(456)
print(DirectoryEntries)
print(AvailableBlocks.insert(0, DirectoryEntries))

答案 2 :(得分:0)

我知道这是一个开发站点,但是如果你想要一个超级简单的方法,没有任何代码,你可以使用PowerPivot,这是一个免费的AddIn。

enter image description here

enter image description here

您可以从此处获取AddIn。

https://support.office.com/en-us/article/Power-Pivot-Add-in-a9c2c6e2-cc49-4976-a7d7-40896795d045

同样,这只是你的另一种选择。我喜欢Parfait的建议!非常优雅,先生!!