こんにちは。Accessの迷宮に足を踏み入れ、データ活用の新たな扉を開こうとしているあなたへ。
これまで「クエリ作成画面」でマウスをカチカチと動かしていた作業から一歩進んで、「コードでクエリを操る」という領域に足を踏み入れましょう。今回は、複数のテーブルを合体させる魔法の呪文「UNION ALL」を、VBAを使って自由自在に生成する方法を伝授します。
これができるようになると、Accessのポテンシャルは劇的に変わりますよ。
—
なぜ「動的SQL」なのか?
通常、クエリ定義(QueryDef)は固定されたものを作りがちです。しかし、業務では「今月はA支店とB支店のデータが欲しい」「来月は全支店のデータが必要」といった変動がつきもの。
毎回手動でクエリを書き換えるのは、ミスのもとであり、何より美しくありません。「必要な時に、必要なパーツを繋ぎ合わせてSQLを作り出す」。これこそが、脱・初心者エンジニアへの登竜門です。
—
UNION ALLの基本をおさらい
`UNION ALL`は、複数の同じ構造を持つテーブルを「縦に積み重ねる」命令です。
SELECT ID, 名前 FROM テーブルA
UNION ALL
SELECT ID, 名前 FROM テーブルB
これをVBAで扱う際、最大の難関は「テーブルの数だけSQLを繋ぐ文字列操作」です。
—
魔法の汎用関数:GenerateUnionSQL
それでは、テーブル名のリストを渡すと、自動的に`UNION ALL`で結合されたSQL文字列を生成する関数を書いてみましょう。
‘ ———————————————————
‘ 機能: テーブル名の配列からUNION ALL SQLを生成する
‘ 引数: tableNames() – 結合したいテーブル名の配列
‘ 戻り値: 完成したSQL文字列
‘ ———————————————————
Public Function GenerateUnionSQL(tableNames() As String) As String
Dim i As Long
Dim sqlBuilder As String
‘ SQLの組み立て開始
For i = LBound(tableNames) To UBound(tableNames)
‘ 各テーブルからデータを抽出するSQLを定義
‘ ※ここでは全カラム取得していますが、必要に応じて調整してください
sqlBuilder = sqlBuilder & “SELECT FROM ” & tableNames(i)
‘ 最後のテーブル以外には UNION ALL を追加する
If i < UBound(tableNames) Then
sqlBuilder = sqlBuilder & " UNION ALL " & vbCrLf
End If
Next i
GenerateUnionSQL = sqlBuilder
End Function
コードの解説:ここがポイント!
1. ループ処理(For文): `LBound`から`UBound`を使うことで、配列の要素数に関係なく柔軟に対応できます。
2. 文字列の連結: `&`演算子を使ってSQLを繋いでいます。`vbCrLf`は改行コードです。これを入れると、後でSQLを確認する際に可読性が格段に上がります。
3. 分岐処理(If文): `UNION ALL`を「テーブルとテーブルの間」だけに挿入するテクニックです。末尾に余計な`UNION ALL`が残るのを防ぐ、プロの気遣いです。
—
実践:QueryDefで動的にクエリを保存する
生成したSQLを実際にAccessの「クエリ」として保存してみましょう。
Public Sub SaveUnionQuery()
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim tables(1 To 2) As String
Set db = CurrentDb
‘ 結合したいテーブル名を指定
tables(1) = “売上2023”
tables(2) = “売上2024”
‘ 先ほどの関数でSQLを作成
Dim mySQL As String
mySQL = GenerateUnionSQL(tables)
‘ クエリが存在すれば削除し、新しく作成する(クリーンな状態を保つ)
On Error Resume Next
db.QueryDefs.Delete “qry_Union_Result”
On Error GoTo 0
Set qdf = db.CreateQueryDef(“qry_Union_Result”, mySQL)
MsgBox “クエリ ‘qry_Union_Result’ を作成しました!”, vbInformation
End Sub
—
初学者が陥りやすい罠と対策
1. 「フィールドの数が合わない」エラー
`UNION ALL`は、結合するテーブル同士で「列の数」と「データ型」が一致している必要があります。もしエラーが出たら、まずは各テーブルのフィールド構成を確認してください。
2. SQLインジェクションへの配慮
今回はテーブル名を固定で渡していますが、もし画面入力から受け取る場合は、必ず「許可されたテーブル名か」をチェックしてください。悪意のある文字列を埋め込まれないための防衛策です。
3. パフォーマンスの意識
`UNION`ではなく`UNION ALL`を使う理由は、`UNION`だと「重複データの排除(ソート処理)」が発生し、動作が重くなるからです。実務では原則`ALL`を使いましょう。
—
先輩からのアドバイス
「コードを書くこと」は目的ではありません。「業務の苦痛を、コードで自動化して消し去ること」が私たちのゴールです。
最初は難しく感じるかもしれませんが、この「文字列を組み立ててSQLを作る」という考え方は、Accessにおける最強の武器の一つです。まずはこのコードをコピーして、ご自身の環境で動かしてみてください。画面に「クエリ」がパッと現れた時の快感は、何物にも代えがたいはずです。
何か詰まったら、いつでも戻ってきてくださいね。応援しています!
