如何在Excel VBA中将来自两个不同数据源创建的两个记录集合并?

5
我的情况是 - 我有一个.xls文件中的数据集和另一个存储在Oracle数据库表中的数据集。我想使用Excel VBA导入这两个数据集,然后执行连接(类似于SQL),最后将数据保存在某个工作簿中。
问题 - 我不知道如何在VBA中获取两个不同的数据集,然后执行连接。在.NET中,有DataSet对象,我们可以将导入的数据保存在其中,然后对其执行任何查询,但是在VBA中,我该怎么做?

这里有很多关于这个问题的谷歌答案。 - MatthewD
谢谢MatthewD,但我该如何执行类似于SQL的连接操作?我没有理解你提供链接中的内容。 - Abhishek Shrirang
这里有另一个更像 SQL 的方法。但你可能需要做一些工作,而不仅仅是一个单独的语句。https://social.msdn.microsoft.com/Forums/en-US/bee47e0a-2a73-4653-aa10-78e1f03cc4e2/need-to-do-left-join-between-two-recordsets - MatthewD
2
如果您将这两组数据都放在Excel中,您可以使用SQL在这两个表格上执行连接操作:http://stackoverflow.com/questions/15304563/how-to-use-sql-joins-in-excel - Tim Williams
@AbhishekUpadhyay 你的两组数据是否完全具有相同的字段?你的Excel版本是2003还是更高,32位/64位? - omegastripes
1个回答

7
考虑以下使用 ADO 的示例。该代码允许在单个 SQL 查询(Jet SQL)中从多个数据源获取数据,特别是从 .xlsx 文件中进行联合,并将结果记录集放入工作表。不幸的是,我没有可用的 Oracle 数据源进行测试,但您也可以通过 ADO 直接连接到 Oracle(像任何其他数据库一样),通过 Oracle ODBC driver 进行连接。
该代码位于 Query.xlsm 中。
Option Explicit

Sub SqlUnionTest()

    Dim strConnection As String
    Dim strQuery As String
    Dim objConnection As Object
    Dim objRecordSet As Object

    strConnection = _
        "Provider=Microsoft.ACE.OLEDB.12.0;" & _
        "User ID=Admin;" & _
        "Data Source='" & ThisWorkbook.FullName & "';" & _
        "Mode=Read;" & _
        "Extended Properties=""Excel 12.0 Macro;"";"

    strQuery = _
        "SELECT * FROM [Sheet1$] " & _
        "IN '" & ThisWorkbook.Path & "\Source1.xlsx' " & _
        "[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;Extended Properties='HDR=YES;'] " & _
        "UNION " & _
        "SELECT * FROM [Sheet1$] " & _
        "IN '" & ThisWorkbook.Path & "\Source2.xlsx' " & _
        "[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;Extended Properties='HDR=YES;'] " & _
        "UNION " & _
        "SELECT * FROM [Sheet1$] " & _
        "IN '" & ThisWorkbook.Path & "\Source3.xlsx' " & _
        "[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;Extended Properties='HDR=YES;'] " & _
        "ORDER BY ContactName;"

    Set objConnection = CreateObject("ADODB.Connection")
    objConnection.Open strConnection
    Set objRecordSet = objConnection.Execute(strQuery)
    RecordSetToWorksheet Sheets(1), objRecordSet
    objConnection.Close

End Sub

Sub RecordSetToWorksheet(objSheet As Worksheet, objRecordSet As Object)

    Dim i As Long

    With objSheet
        .Cells.Delete
        For i = 1 To objRecordSet.Fields.Count
            .Cells(1, i).Value = objRecordSet.Fields(i - 1).Name
        Next
        .Cells(2, 1).CopyFromRecordset objRecordSet
        .Cells.Columns.AutoFit
    End With

End Sub

注意,ThisWorkbook.Path 路径中不应包含 '。否则,您需要将其替换为 '' 进行转义。
此外,在与 Query.xlsm 相同的文件夹中有三个 data source 文件。

Source1.xlsx:

Source1.xlsx

Source2.xlsx:

Source2.xlsx

Source3.xlsx:

Source3.xlsx

生成的工作表如下:

Query.xlsm result

对我来说,它可以在64位版本的Excel 2013上运行。为了使其与 .xls 和 Excel 2003 兼容(其中提供程序 ACE.OLEDB.12.0 没有安装),您需要将 Provider=Microsoft.ACE.OLEDB.12.0; 替换为 Provider=Microsoft.Jet.OLEDB.4.0;,并且在扩展属性中也要将 Excel 12.0 Macro; /Excel 12.0; 替换为 Excel 8.0;。您可以轻松地向查询添加 WHERE 子句和其他SQL内容。实际上,连接对象的数据源不仅限于代码所放置的 Query.xlsm 文件。它可能是另一个数据源,与可用提供程序之一兼容,可以基于文件或服务器。在 http://www.connectionstrings.com/ 上查找更多数据源的连接字符串。

考虑以使用的策略开始回答:VBA ADO连接。甚至建议OP也可以使用ADO直接连接到Oracle(像任何其他数据库一样),使用Oracle ODBC驱动程序 - Parfait
感谢您的示例。 - Abhishek Shrirang
@AbhishekUpadhyay 如果您觉得这个答案有帮助,请点击接受答案。 - omegastripes
@omegastripes 抱歉评论了一篇旧帖子,但找不到任何关于这种SELECT语句的文档。我想知道的是,如果我用位于不同文件夹中的2个csv文件替换Excel文件,我能否将它们JOIN在一起?现在我遇到了语法错误。我没有使用ODBC MICROSOFT ACCESS TEXT DRIVER,因为我发现它无法处理路径中的空格。我可以将代码作为新帖子分享。请给予建议。 - sifar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接