使用VBA和ADODB在Excel中组合表

时间:2014-10-31 11:59:31

标签: sql excel vba excel-vba adodb

使用Excel VBA我希望能够将excel中的两个表与一个公共密钥组合在一起。我已经建议将ADODB作为一种方法,但我对任何其他更有效/更优雅的方法都持开放态度。请参阅下面的最小示例:

我从下面开始......

Sheet 1中

    A     B       C
 1 type year1   year2
 2 aaa  100     110
 3 bbb  220     240
 4 ccc  304     200
 5 ddd  20      30
 6 eee  440     20

Sheet 2中

    A     B       C
 1 type year1   year2
 2 bbb  10      76
 3 ccc  44      39
 4 ddd  50      29
 5 eee  22      23
 6 fff  45      55

并希望将它结合起来,以便我得到以下结果:

表Sheet 3

    A     B       C       D       E
 1 type year1   year2   year1   year2
 2 aaa  100      110      0       0
 3 bbb  220      240      10      76
 4 ccc  304      200      44      39
 5 ddd  20       30       50      29
 6 eee  440      20       22      23
 7 fff  0        0        45      55

已经完成了一些谷歌搜索和SQL类型的外连接似乎很接近但不确定如何实现它。

以下是目前用于尝试和实施它的代码......

Option Explicit



Sub JoinTables()

 Dim cn As ADODB.Connection
 Set cn = New ADODB.Connection


 With cn
     .Provider = "Microsoft.Jet.OLEDB.4.0"
     .ConnectionString = "Data Source=" & ThisWorkbook.FullName & ";" & _
         "Extended Properties=Excel 8.0;"
     .Open
 End With

 Dim rs As ADODB.Recordset
 Set rs = New ADODB.Recordset

 rs.Open "SELECT * FROM [Sheet1$] OUTER JOIN [Sheet2$] ON [Sheet1$].[type] = " & _
     "[Sheet2$].[type]", cn

 With Worksheets("Sheet3")
     .Cells(2, 1).CopyFromRecordset rs
 End With

 rs.Close
 cn.Close

 End Sub

1 个答案:

答案 0 :(得分:1)

所以JET不支持完全外连接所以我最终不得不使用左连接重写它,然后右连接来检查我们错过的类型:

Sub Button1_Click()

 Dim cn As ADODB.Connection
 Set cn = New ADODB.Connection


 With cn
     .Provider = "Microsoft.Jet.OLEDB.4.0"
     .ConnectionString = "Data Source=" & ThisWorkbook.FullName & ";" & _
         "Extended Properties='Excel 8.0;HDR=Yes;IMEX=1'"
     .Open
 End With

 Dim rs As ADODB.Recordset
 Set rs = New ADODB.Recordset



  rs.Open "SELECT [Sheet1$].[Type] AS Type" & _
  " ,[Sheet1$].[Year1] as Year11" & _
  " ,[Sheet1$].[Year2] as Year21" & _
  " ,[Sheet2$].[Year1] as Year12" & _
  " ,[Sheet2$].[Year2] as Year22" & _
  " FROM [Sheet1$] LEFT JOIN [Sheet2$] ON [Sheet1$].[type] = " & _
     "[Sheet2$].[type] UNION ALL " & _
     " SELECT [Sheet2$].[Type] AS Type" & _
  " ,[Sheet1$].[Year1] as Year11" & _
  " ,[Sheet1$].[Year2] as Year21" & _
  " ,[Sheet2$].[Year1] as Year12" & _
  " ,[Sheet2$].[Year2] as Year22" & _
  " FROM [Sheet1$] RIGHT JOIN [Sheet2$] ON [Sheet1$].[type] = " & _
 "[Sheet2$].[type] WHERE [Sheet2$].[type] NOT IN (SELECT type FROM [Sheet1$]) ", cn

 With Worksheets("Sheet3")
     .Cells(2, 1).CopyFromRecordset rs
 End With


 rs.Close
 cn.Close

End Sub

流程是这样的:

  1. 获取Sheet1和Sheet2之间的匹配
  2. 获取我们在上一个查询中未获得的Sheet2和Sheet1之间的匹配
  3. 如果您有任何疑问或遗漏任何问题,请告诉我。

    编辑了查询:我意识到不需要第三步而且过度了。