简体   繁体   English

使用VBA-Excel进行跨多个数据库的SQL查询

[英]Using VBA-Excel for an SQL query across multiple databases

Using Excel 2010, SQL and DAO 使用Excel 2010,SQL和DAO

I am trying to execute a query against tables which reside outside the current spreadsheet. 我试图对驻留在当前电子表格之外的表执行查询。 This would be trivial, inside Access, with linked tables/databases, but using VBA in excel, I am stymied. 在Access中,使用链接的表/数据库,这将是微不足道的,但是我在excel中使用VBA却很困难。

Presuming these: 假定这些:

ExcelFileOne; Tab; various headed field/columns
ExcelFileTwo; Tab; various headed field/columns

I want to execute a query inside a third excel file, that goes something like this [using dot notation for explanation, not coding....] -- a simple example: 我想在第三个excel文件中执行查询,该查询类似于[使用点表示法进行解释,而不是编码...]-一个简单的示例:

SELECT FileOne.[Tab$].Fields, FileTwo.[Tab$].Fields, etc.
    FROM FileOne, FileTwo, Thisworkbook
    WHERE (FileOne.[Tab$].field2 <> FileTwo.[Tab$].Field2) 
        AND (ThisWorkbook.[Tab$].Field1 ....)

Basically, I want to duplicate what Access will do natively, for that linked file. 基本上,我想复制该链接文件的Access本地操作。

Pointers in the right directions ? 指向正确方向的指针?

[[ I could use a pointer towards why using "Excel 8.0..." in a connection works or fails on Excel2010, with macro files, and how to load the 12 or 14 variant in a network/system closed to users.... ]] [[我可以使用一个指针,为什么在带有宏文件的Excel2010上连接中使用“ Excel 8.0 ...”可以正常工作或失败,以及如何在对用户关闭的网络/系统中加载12或14变体... ]]。

You can indeed query other workbooks using DAO and ADO directly in a SQL statement and likewise query Access databases tables by simply referencing their paths. 您确实可以直接在SQL语句中使用DAO和ADO查询其他工作簿,并且同样可以通过简单地引用它们的路径来查询Access数据库表。 Conversely, within an Access query you can query Excel workbooks! 相反,在Access查询中,您可以查询Excel工作簿! This is testament to the fact that Jet/ACE SQL engine (Windows .dll files) is not restricted to any one MS Office product or Windows program but a tool for all. 这证明了Jet / ACE SQL引擎(Windows .dll文件)不限于任何一种MS Office产品或Windows程序,而是针对所有工具的事实。

In both examples below, macros make a direct connection to first workbook and in SQL query each indirectly connects to second workbook. 在下面的两个示例中,宏都直接连接到第一个工作簿,而在SQL查询中,每个宏都间接连接到第二个工作簿。 You can run code inside or outside either workbooks. 您可以在两个工作簿内部或外部运行代码。 Also both runs genric INNER JOIN on FileOne and FileTwo worksheets but any compliant Jet/ACE SQL statement should work. 两者都在FileOneFileTwo工作表上运行通用的INNER JOIN ,但是任何兼容的Jet / ACE SQL语句都应该起作用。 And both output query results in a pre-existing RESULTS tab. 并且两个输出查询的结果都在一个预先存在的“ 结果”选项卡中。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM