如何在 VBA 中使用 SQL 将两个工作簿与一个公共列合并

Posted

技术标签:

【中文标题】如何在 VBA 中使用 SQL 将两个工作簿与一个公共列合并【英文标题】:How to merge two workbooks with one common column using SQL in VBA 【发布时间】:2018-10-24 19:03:52 【问题描述】:

我相信我也可以通过宏来做到这一点,但我想介绍一下 VBA 中的 ADODB 和 SQL 查询。数据集不在 Access 中,而是在单独的工作簿中,两个工作簿的 SQL 查询如下:

SELECT getRollpHierRpt.Field1, ['App].[Master Book Name], ['App].[App Book Name], ['App].[Secondary App Book Name], ['App].[App Code], ['App].[App Book Status], ['App].[Book Transit], ['App].[Transit Desc], ['App].[Legal Entity Id], ['App].[Legal Entity Desc]
FROM ['App] INNER JOIN getRollpHierRpt ON ['App].[Book Transit] = getRollpHierRpt.Field1;

我在互联网上看到的示例包括连接到 Access/SQL 服务器,但如果数据集是两个 excel 工作簿?

Sub MergeIt()
Dim conn1 As New ADODB.Connection
Dim conn2 As New ADODB.Connection
 With conn1
.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data 
Source=C:\Users\amzubaid\Desktop\Practice Merging\13-10-2017.xlsm;" & 
"Extended Properties=""Excel 12.0 Macro;HDR=YES';IMEX=1"""
.Open
  End With
With conn2
.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data 
Source=C:\Users\amzubaid\Desktop\Practice Merging\20181015-Practice.xlsm;" & "Extended Properties=""Excel 12.0 Macro;HDR=YES';IMEX=1"""
  .Open
 End With
Dim rsSmall As New Recordset
rsSmall.Open "select [Field1] from [getRollpHierRpt$]", conn1
 Dim r As Range
Dim rsBig As New Recordset
Do
Set r = Range("a" & Rows.Count).End(xlUp).Offset(1, 0) 'first unoccupied cell

rsBig.Open "select [App Code],[Legal Entity Desc]," & rsSmall("Field1") & " 
 As GetRollPH from [getRollpHierRpt$] where [BookTransit] = " & 
 rsSmall("Field1"), conn2
 r.CopyFromRecordset rsBig
rsBig.Close
rsSmall.MoveNext
Loop Until rsSmall.EOF  'end if file
rsSmall.Close
conn1.Close
conn2.Close

End Sub

【问题讨论】:

【参考方案1】:

您需要设置与每个工作簿的连接。实际上,这依赖于将每个工作簿视为数据库中的一个表。每个工作簿中必须有列标题,它们被视为字段名称。试试this了解详情

好的,所以这似乎不可能 - 所以一种可能的解决方法是打开较小的表,然后单步执行它并使用各个值从较大的表中检索所需的记录:这是一个使用两个名为 Testfile1 的工作簿的示例和testfile2。每个都包含一个名为“test”的工作表和一些数据,testfile2 中的列标题称为“TestC”和“TestD”,而 testfile1 中的第一个(链接)文件称为“TestA”。 (这需要在 VBE、工具、参考中引用 Microsoft Active X Data Objects 库)

Sub TwoFiles()
Dim conn1 As New ADODB.Connection
Dim conn2 As New ADODB.Connection
With conn1
    .ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=P:\testfile1.xlsm;" & "Extended Properties='Excel 12.0 Macro;HDR=YES';"
    .Open
End With
With conn2
.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=P:\testfile2.xlsm;" & "Extended Properties='Excel 12.0 Macro;HDR=YES';"
.Open
End With
Dim rsSmall As New Recordset
rsSmall.Open "select [testA] from [test$]", conn1
Dim r As Range
Dim rsBig As New Recordset
Do
Set r = Range("a" & Rows.Count).End(xlUp).Offset(1, 0) 'first unoccupied cell

rsBig.Open "select [TestC],[TestD]," & rsSmall("testA") & " As GetRollPH from [test$] where [testC] = " & rsSmall("testA"), conn2
r.CopyFromRecordset rsBig
rsBig.Close
rsSmall.MoveNext
Loop Until rsSmall.EOF  'end if file
rsSmall.Close
conn1.Close
conn2.Close


End Sub

【讨论】:

完美。谢谢! 所以在他做的例子中,他只使用了一个工作簿作为数据源。如果我想使用两个工作簿作为数据库,我将如何继续这样做。或者,是否有必要将它们都用作数据库? 所以由于某种原因,我的访问数据库无法获取源文件。它说: Microsoft Access 数据库引擎找不到对象“Sheet1$A1:NC3”。确保对象存在并且正确拼写其名称和路径名。 rsSmall.Open "select [Field1] from [getRollpHierRpt$]", conn1 假定工作表 GetRollpHierRpt 中的 A1 包含文本“Field1” 你确定工作表的名称是那个并且 A1 有那个文本吗?

以上是关于如何在 VBA 中使用 SQL 将两个工作簿与一个公共列合并的主要内容,如果未能解决你的问题,请参考以下文章

关于如何在 Oracle 数据库中使用 VBA 执行 SQL 脚本的建议

如何使用sql语句和vba将数据从MS-Access导入excel power查询?

如果主工作簿与主工作簿匹配,则从工作簿中查找和循环并复制值

如何在 SQL 语句中引用组合框并在 VBA 中运行该语句

在excel中如何使用vba实现将sql的数据快速写入excel

使用 VBA 将 Excel 表连接到 SQL Server