【VBAリファレンス】SQL入門データの取得:条件指定(SELECT,WHERE)

スポンサーリンク

Excel VBAエンジニアのためのSQL入門:SELECTとWHEREによるデータ抽出の極意

Excel VBAを操るエンジニアにとって、AccessデータベースやSQL Server、あるいはSQLiteといった外部データベースとの連携は、業務効率化の最終到達点とも言えます。VBAだけで複雑なループ処理を記述する時代は終わり、現在は「必要なデータをSQLで抽出し、結果をExcelに流し込む」という設計が主流です。本記事では、SQLの基本中の基本である「データの取得」に焦点を当て、SELECT文とWHERE句を使いこなすための技術的詳細を解説します。

SQLにおけるデータ取得の基本構造

SQL(Structured Query Language)は、データベースから特定の情報を「宣言的」に取得するための言語です。VBAが「どうやって(How)」処理を行うかを記述する手続き型言語であるのに対し、SQLは「何を(What)」取得したいかを記述する宣言型言語です。

データの取得にはSELECT文を用います。最も基本的な構文は以下の通りです。

SELECT カラム名 FROM テーブル名;

ここで重要なのは、データベースの世界ではExcelのシート全体を「テーブル」と見なし、列を「カラム(フィールド)」、行を「レコード」と呼ぶ点です。VBAでRangeオブジェクトを操作する際、行と列をインデックスで指定していましたが、SQLでは「カラム名」を指定して値を取り出します。

SELECT文によるカラムの選択

全てのカラムを取得したい場合は「*(アスタリスク)」を使用しますが、実務においては推奨されません。必要なカラムのみを明示的に指定することで、ネットワークトラフィックの削減や、メモリの節約、そしてコードの可読性向上につながります。

例えば、顧客データベースから「名前」と「電話番号」だけを取得したい場合、以下のように記述します。

SELECT 顧客名, 電話番号 FROM T_顧客マスタ;

VBAでADODB.Recordsetを使用してデータを取得する際、SELECTで指定した順序でデータが格納されます。このため、SELECT文での指定順序を意識することは、VBA側のコード(rs.Fields(0).Valueなど)の安定性に直結します。

WHERE句による条件指定の技術

データベースに格納された全件を取得するケースは稀です。多くの場合、特定の条件に合致するレコードだけを抽出する必要があります。ここで登場するのがWHERE句です。WHERE句はFROM句の直後に配置し、レコードを絞り込むための論理条件を記述します。

WHERE句で使用できる主な演算子は以下の通りです。

・比較演算子:=, <>, <, <=, >, >=
・論理演算子:AND, OR, NOT
・パターンマッチング:LIKE
・範囲指定:BETWEEN
・値のリスト:IN
・欠損値の判定:IS NULL

例えば、「売上金額が100万円以上、かつ地域が東京」という条件でデータを抽出する場合、SQLは以下のようになります。

SELECT 売上ID, 金額, 地域 FROM T_売上 WHERE 金額 >= 1000000 AND 地域 = ‘東京’;

ここで注意が必要なのは、文字列リテラルを記述する際のシングルクォーテーション(’)です。VBAの文字列連結と混同しやすいため、SQL文全体をダブルクォーテーションで囲み、内部の文字列をシングルクォーテーションで囲むというルールを徹底してください。

LIKE演算子によるあいまい検索

実務において、完全一致だけでなく「~を含む」といったあいまい検索は頻繁に発生します。LIKE演算子とワイルドカード(%:0文字以上の任意の文字列)を組み合わせます。

例えば、「名前」に「田中」が含まれるレコードを検索する場合:

SELECT * FROM T_顧客 WHERE 名前 LIKE ‘%田中%’;

この「%」は、VBAの「*」とは異なることに注意してください。Accessのクエリ(DAO)では「*」を使用しますが、標準的なSQL(ADO/SQL Server/SQLite等)では「%」を使用します。この違いでエラーに悩まされるエンジニアは非常に多いため、接続先のデータベースエンジンが何であるかを常に意識してください。

VBAとSQLの連携サンプルコード

以下に、ADO(ActiveX Data Objects)を使用してデータベースから条件付きでデータを取得し、Excelシートへ展開する標準的なコード例を示します。


Sub GetDataFromDatabase()
    Dim conn As Object
    Dim rs As Object
    Dim strSQL As String
    Dim connStr As String
    
    ' 接続文字列(環境に合わせて変更)
    connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\DB\Sales.accdb;"
    
    ' SQL文の構築
    strSQL = "SELECT 顧客名, 売上金額 FROM T_売上 " & _
             "WHERE 地域 = '大阪' AND 売上金額 > 50000 " & _
             "ORDER BY 売上金額 DESC;"
    
    Set conn = CreateObject("ADODB.Connection")
    Set rs = CreateObject("ADODB.Recordset")
    
    conn.Open connStr
    rs.Open strSQL, conn
    
    ' シートへの書き出し
    If Not rs.EOF Then
        Sheet1.Range("A2").CopyFromRecordset rs
    End If
    
    ' 後処理
    rs.Close
    conn.Close
    Set rs = Nothing
    Set conn = Nothing
End Sub

実務におけるプロフェッショナルなアドバイス

1. SQL文の可読性
SQL文をVBAのコード内で1行に詰め込むのは避けましょう。上記サンプルコードのように、アンダースコア(_)を用いた連結を行い、改行を入れて整形してください。また、予約語(SELECT, FROM, WHERE等)はすべて大文字で記述するのが業界の慣習です。

2. インデックスの意識
WHERE句で指定するカラムには、データベース側でインデックスを貼ることを検討してください。数万件以上のレコードを扱う場合、インデックスがないと検索速度が劇的に低下します。VBA側でいくらコードを高速化しても、データベース側のクエリが遅ければ意味がありません。

3. SQLインジェクションへの対策
VBAの入力フォームから受け取った値を直接SQL文に連結するのは非常に危険です。悪意のあるユーザーがSQL文を改ざんする「SQLインジェクション」攻撃を受ける可能性があります。入力値は必ずサニタイズ(エスケープ処理)を行うか、パラメータクエリを利用して安全にデータを渡す習慣を身につけましょう。

4. NULL値の取り扱い
データベースにおいて、値が「空」であることを示すNULLは、通常の比較演算子(=)では拾えません。「IS NULL」または「IS NOT NULL」を正しく使い分けることが、データの欠損を防ぐ鍵となります。

まとめ

SQLによるデータ取得は、現代のExcel業務自動化における中核技術です。SELECT文で必要なカラムを絞り込み、WHERE句で的確に条件を指定する。この基本動作をマスターするだけで、VBAのコード量は激減し、処理速度とメンテナンス性は飛躍的に向上します。

最初は複雑に感じるかもしれませんが、データベースと対話するこの言語は、一度習得すれば一生モノのスキルとなります。まずは手元の小さなデータベースから、WHERE句を使った条件抽出を試してみてください。エラーが出た際も、それはデータベースがあなたに「SQLの構造が正しくない」と教えてくれているサインです。焦らずログを確認し、一歩ずつプロフェッショナルなデータ操作術を磨き上げていきましょう。

タイトルとURLをコピーしました