使用 VBA-Excel 跨多个数据库进行 SQL 查询
Posted
技术标签:
【中文标题】使用 VBA-Excel 跨多个数据库进行 SQL 查询【英文标题】:Using VBA-Excel for an SQL query across multiple databases 【发布时间】:2016-11-28 01:15:03 【问题描述】:使用 Excel 2010、SQL 和 DAO
我正在尝试对驻留在当前电子表格之外的表执行查询。在 Access 中,使用链接表/数据库,这将是微不足道的,但在 excel 中使用 VBA,我被阻碍了。
假设这些:
ExcelFileOne; Tab; various headed field/columns
ExcelFileTwo; Tab; various headed field/columns
我想在第三个 excel 文件中执行一个查询,类似于这样 [使用点符号进行解释,而不是编码......]——一个简单的例子:
SELECT FileOne.[Tab$].Fields, FileTwo.[Tab$].Fields, etc.
FROM FileOne, FileTwo, Thisworkbook
WHERE (FileOne.[Tab$].field2 <> FileTwo.[Tab$].Field2)
AND (ThisWorkbook.[Tab$].Field1 ....)
基本上,我想复制 Access 将在本机上为该链接文件执行的操作。
指向正确方向的指针?
[[我可以使用一个指针来说明为什么在 Excel2010 上使用宏文件在连接中使用“Excel 8.0...”可以工作或失败,以及如何在对用户关闭的网络/系统中加载 12 或 14 变体....]]
【问题讨论】:
研究EXCEL的ODBC驱动;也许从这里开始:connectionstrings.com/microsoft-excel-odbc-driver Excel 不是数据库服务器,也没有自带数据库引擎。它只能借助ADO
或DAO
等外部库来理解SQL。如果您有 Office 2016 或 2013 并安装了PowerQuery,那么现在可以使用此新加载项。如果没有,您将不得不依靠 Access 或 SQL-Server 为您完成这项工作(或将两张表传输到一个文件中,然后使用 VBA 将它们转换/相乘以满足您的需要)。
【参考方案1】:
您确实可以在 SQL 语句中直接使用 DAO 和 ADO 查询其他工作簿,同样通过简单地引用它们的路径来查询 Access 数据库表。相反,在 Access 查询中,您可以查询 Excel 工作簿!这证明了 Jet/ACE SQL 引擎(Windows .dll 文件)不限于任何一种 MS Office 产品或 Windows 程序,而是适用于所有人的工具。
在下面的两个示例中,宏直接连接到第一个工作簿,而在 SQL 查询中,每个宏都间接连接到第二个工作簿。您可以在任一工作簿内部或外部运行代码。两者都在 FileOne 和 FileTwo 工作表上运行 genric INNER JOIN
,但任何兼容的 Jet/ACE SQL 语句都应该可以工作。并且两个输出查询结果都在预先存在的 RESULTS 选项卡中。
DAO
Dim dbE As Object, db As Object, rst As Object
Dim sqlString As String
Dim i As Integer
Const dbOpenDynaset = 2, dbReadOnly = 4
' OPEN DB CONNECTION
Set dbE = CreateObject("DAO.DBEngine.120") 'ALSO TRY: DAO.DBEngine.35 OR .36
Set db = dbE.OpenDatabase("C:\Path\To\FileOne.xlsm", False, True, "Excel 12.0 Xml;HDR=Yes")
' OPEN QUERY RECORDSET
sqlString = " SELECT * FROM [TAB$] t1" _
& " INNER JOIN (SELECT * FROM" _
& " [Excel 12.0 Xml;HDR=Yes;Database=C:\Path\To\FileTwo.xlsm].[TAB$]) t2" _
& " ON t1.ID = t2.ID"
Set rst = db.OpenRecordset(sqlString, dbOpenDynaset, dbReadOnly)
' COLUMNS
For i = 1 To rst.Fields.Count
Worksheets("RESULTS").Cells(1, i) = rst.Fields(i - 1).Name
Next i
' DATA ROWS
Worksheets("RESULTS").Range("A2").CopyFromRecordset rst
rst.Close
db.Close
Set rst = Nothing
Set db = Nothing
Set dbE = Nothing
ADO
Dim conn As Object, rst As Object, fld As Object
Dim strConnection As String, strSQL As String
Dim i As Integer
Set conn = CreateObject("ADODB.Connection")
Set rst = CreateObject("ADODB.Recordset")
' OPEN DB CONNECTION
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;" _
& "Data Source='C:\Path\To\FileOne.xlsm';" _
& "Extended Properties=""Excel 12.0 Xml;HDR=YES;"";"
conn.Open strConnection
' OPEN QUERY RECORDSET
strSQL = " SELECT * FROM [TAB$] t1" _
& " INNER JOIN (SELECT * FROM" _
& " [Excel 12.0 Xml;HDR=Yes;Database=C:\Path\To\FileTwo.xlsm].[TAB$]) t2" _
& " ON t1.ID = t2.ID"
rst.Open strSQL, conn
' COLUMNS
For i = 1 To rst.Fields.Count
Worksheets("RESULTS").Cells(1, i) = rst.Fields(i - 1).Name
Next i
' DATA ROWS
Worksheets("RESULTS").Range("A2").CopyFromRecordset rst
rst.Close
conn.Close
Set rst = Nothing
Set conn = Nothing
【讨论】:
谢谢...!其他曲折的想法:1)我看到了 dbe 对象,这是创建对所有三个文件 [本地和外部] 的查询可以生存的奇异世界吗? 2)为什么 12,如果 8 对 12 不起作用[因为我封闭的办公室机器上缺少 12,当我无法加载软件时该怎么办,等等...] 3)我假设 36 是在我的 MS 安装中引用 DAO 3.6,对吗? 4) 为什么不是 DAO 连接,就像围绕对象模型的工具一样,我也看到了。 使用您安装的任何 DAO 版本。或者使用不需要版本且可转换为其他数据库(mysql、SQL Server 等)的 ADO——只需更改字符串连接和 SQL 语句。如前所述,这里的示例首先连接到第一个 Excel 文件,然后在 SQL 查询中连接到第二个。 这行得通,@Parfait,但是当我接触 CSV 文件时,将外部引用放在 FROM 子句中时遇到错误。你能顶峰吗? ***.com/questions/38818686/…>以上是关于使用 VBA-Excel 跨多个数据库进行 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章