如何连接从 excel vba 中的两个不同数据源创建的两个记录集
How to join two recordset created from two different data source in excel vba
我的情景是 -
我在 .xls 文件中有一组数据,在 oracle 数据库中有另一组数据 table。我想使用 excel vba 导入这两个数据,然后执行连接(sql 之类),最后将数据保存在某个工作簿中。
问题 -
我不知道如何在 vba 中获取两组不同的数据,然后执行连接。
在 .Net 中有 DataSet 对象,我们可以在其中保存导入的数据,然后对其执行任何查询,但是 vba 我该怎么做?
考虑以下使用 ADO 的示例。该代码允许在单个 SQL 查询 (Jet SQL) 中从多个数据源获取数据,特别是从 .xlsx
文件创建联合,并将结果记录集放入工作表。不幸的是,我没有可用的 Oracle 数据源来测试,尽管您也可以通过 Oracle ODBC driver.
使用 ADO(与任何其他数据库一样)直接连接到 Oracle
代码放在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
:
Source2.xlsx
:
Source3.xlsx
:
生成的工作表如下:
它适用于我的 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/
上为您的数据源查找更多连接字符串
我的情景是 - 我在 .xls 文件中有一组数据,在 oracle 数据库中有另一组数据 table。我想使用 excel vba 导入这两个数据,然后执行连接(sql 之类),最后将数据保存在某个工作簿中。
问题 - 我不知道如何在 vba 中获取两组不同的数据,然后执行连接。 在 .Net 中有 DataSet 对象,我们可以在其中保存导入的数据,然后对其执行任何查询,但是 vba 我该怎么做?
考虑以下使用 ADO 的示例。该代码允许在单个 SQL 查询 (Jet SQL) 中从多个数据源获取数据,特别是从 .xlsx
文件创建联合,并将结果记录集放入工作表。不幸的是,我没有可用的 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
:
Source2.xlsx
:
Source3.xlsx
:
生成的工作表如下:
它适用于我的 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/