表の結合。便利ですよね。
Excelではvlookup等の関数を使用して結合することが多いです。
今回は関数ではなくVBAでSQLを使用して表の結合を行いましたが、その際に2つではなく3つの表の結合をする際にちょっと詰まってしまったので備忘録。
例題
今回はこのような3つの表を結合して1つの表を作ります。
※元ネタは例のごとくなんちゃって個人情報 より
エラー症状
上記を実現するために以下のSQLを記載しましたが、エラーが発生します。
select A.*,B.血液型,C.都道府県名 from [w$A1:C21] as A left join [w$E17:F21] as B on A.血液型No = B.血液型No left join [w$E1:F7] as C on A.都道府県No = C.都道府県No
SQLで結合(表2つ)
まずはSQLで2つの表を結合してみます。
Sub 二表結合() '--Microsoft ActiveX Data Objects X.X Libraryを参照設定 Dim myCON As ADODB.Connection: Set myCON = New ADODB.Connection myCON.Provider = "Microsoft.ACE.OLEDB.12.0" myCON.Properties("Extended Properties") = "Excel 12.0;IMEX=1" myCON.Open ThisWorkbook.FullName Dim myRS As ADODB.Recordset: Set myRS = New ADODB.Recordset Dim mySQL As String mySQL = "select A.*,B.血液型 from [w$A1:C21] as A" mySQL = mySQL & " left join [w$E17:F21] as B on A.血液型No = B.血液型No" myRS.Open mySQL, myCON, adOpenStatic Dim i As Long For i = 1 To myRS.Fields.Count wsSQL.Cells(26, i).Value = myRS.Fields(i - 1).Name Next wsSQL.Range("A27").CopyFromRecordset myRS myRS.Close: Set myRS = Nothing myCON.Close: Set myCON = Nothing End Sub
2表であれば当然普通にLeft Join句を使用すれば結合することができます。
対処法
3表の結合をするにはLeft Join句を重ね書きするだけでは冒頭のようにエラーが発生します。
対処法として下記のようにテーブル指定を「()」で括るようにします。
select * from ((テーブル名 as A left join 結合テーブル s B on A.列名 = B.列名) left join 結合テーブル2 as C on A.列名 = C.列名)
SQLで結合(表3つの場合)
上記を反映したコードが以下になります。
Sub 三表結合() '--Microsoft ActiveX Data Objects X.X Libraryを参照設定 Dim myCON As ADODB.Connection: Set myCON = New ADODB.Connection myCON.Provider = "Microsoft.ACE.OLEDB.12.0" myCON.Properties("Extended Properties") = "Excel 12.0;IMEX=1" myCON.Open ThisWorkbook.FullName Dim myRS As ADODB.Recordset: Set myRS = New ADODB.Recordset Dim mySQL As String mySQL = "select A.*,B.血液型,C.都道府県名 from" mySQL = mySQL & " (([w$A1:C21] as A left join [w$E17:F21] as B on A.血液型No = B.血液型No)" mySQL = mySQL & " left join [w$E1:F7] as C on A.都道府県No = C.都道府県No)" myRS.Open mySQL, myCON, adOpenStatic Dim i As Long For i = 1 To myRS.Fields.Count wsSQL.Cells(26, i).Value = myRS.Fields(i - 1).Name Next wsSQL.Range("A27").CopyFromRecordset myRS myRS.Close: Set myRS = Nothing myCON.Close: Set myCON = Nothing End Sub
上記のコードであればエラーもなく下記のように3表を結合した表を作成することが出来ます。