【入門編】動的SQL生成時の「引用符(’)」エスケープ処理を自動化する汎用関数 – Access VBA解析バイブル

スポンサーリンク

こんにちは!Access VBAでの開発、日々お疲れ様です。
マクロの記録から一歩踏み出し、自分の手でコードを書いてシステムをコントロールする面白さを感じ始めている頃ではないでしょうか。

さて、VBAを使ってデータベースを操作していると、避けて通れないのが「SQL(エスキューエル)」の組み立てです。画面のテキストボックスに入力された値を使ってデータを検索したり追加したりする……業務アプリでは毎日のように書く処理ですよね。

ここで、多くの開発者が最初に、そして何度も直面する「魔物」がいます。
それが、シングルクォーテーション( `’` )によるSQL構文エラーです。

今回は、この厄介なエスケープ処理を完全に自動化し、あなたのコードを「絶対にエラーで止まらない頑健なシステム」に生まれ変わらせる汎用関数を授けましょう。ここをクリアすれば、Access VBAの基本はバッチリですよ!

—

1. なぜSQLの「引用符」でエラーが起きるのか?

まずは敵を知ることから始めましょう。
例えば、画面の検索窓(テキストボックス `txtSearch`)にユーザーが以下のように入力したとします。

> O’Reilly (プログラミング書籍で有名なオライリーです)

これをVBAでSQL文に組み込もうとして、次のようなコードを書いたとします。

‘ 危険なコードの例
Dim strSQL As String
strSQL = “SELECT FROM T_Books WHERE BookName = ‘” & Me.txtSearch.Value & “‘;”

このとき、パソコン(Accessのエンジン)が実際に受け取る文字列はどうなるでしょうか?

SELECT FROM T_Books WHERE BookName = ‘O’Reilly’;

……お気づきでしょうか?
`O` の後ろにあるシングルクォーテーションで、「文字列がここで終わり」とSQLに誤解されてしまうのです。その結果、残りの `Reilly’;` が予期せぬ構文とみなされ、無情な「実行時エラー(構文エラー)」が爆誕します。

撲滅すべき悪夢のパターン

  • 人名や社名に `O’Brien` や `D’souza` が含まれているとき
  • 備考欄に `「これ、ダメでした。」` のような全角・半角の引用符や、文章中のアポストロフィが混ざるとき

これらを人力で一つずつチェックするのは、バグを生む原因でしかありません。だからこそ、「自動で安全な形に変換する関数」をあらかじめ用意しておく必要があるのです。

—

2. 解決策:シングルクォーテーションを無害化する極意

SQLの世界では、文字列リテラルの中にあるシングルクォーテーションは、「2つ重ねる(`”`)」ことで「これはただの文字ですよ(エスケープ)」とエンジンに伝えるルールになっています。

つまり、先ほどの `O’Reilly` なら、SQL文の中で `O”Reilly` と表現されていればエラーになりません。

この変換(置換)を、VBAの `Replace` 関数を使って一瞬で行うユーティリティ関数を作りましょう。

—

3. 実装:コピペで使える「安全・確実」な汎用エスケープ関数

あなたのプロジェクトの「標準モジュール」(なければ新規作成してください)に、以下のコードをそのまま貼り付けてください。

Option Explicit

‘ ==============================================================================
‘ モジュール名: modDatabaseUtils
‘ 概要 : データベース操作に関する汎用ユーティリティ
‘ ==============================================================================

/

  • SQLの文字列リテラル用にシングルクォーテーションをエスケープする
  • @param ByVal vValue As Variant 処理対象の値(テキストボックス等の値)
  • @return String SQLに埋め込んでも安全に加工された文字列

/
Public Function SafeSQLStr(ByVal vValue As Variant) As String

‘ 1. 万が一のNull(未入力)対策:Nullなら空文字を返す
If IsNull(vValue) Then
SafeSQLStr = “”
Exit Function
End If

‘ 2. 数値型などの場合も考慮し、一度文字列に変換
Dim strVal As String
strVal = CStr(vValue)

‘ 3. 【核心】シングルクォーテーション(‘)を2つ(”)に置換する
‘ これによりSQLの構文破壊を防ぐ
strVal = Replace(strVal, “‘”, “””)

‘ 4. 前後のシングルクォーテーションで囲んで返す
‘ ※SQL文を組み立てる際、値部分をこの関数だけで完結させるとミスが減ります
SafeSQLStr = “‘” & strVal & “‘”

End Function

この関数のスマートなポイント

1. Nullへの耐性: 画面の入力欄が空っぽ(Null)でもエラーになりません。自動的に空文字(`”`)として安全に処理されます。
2. 囲みまで自動化: 関数の戻り値自体に最初からシングルクォーテーション(`”`)を付与しているため、SQL文を書くときのクォーテーションの付け忘れ・付け間違いが物理的に起きなくなります。

—

4. 実践:動的SQL生成でのスマートな使い方

先ほどのエスケープ関数を使って、実際にクエリ定義(`QueryDef`)や `DoCmd.RunSQL` で動的SQLを組み立ててみましょう。

Public Sub SearchBooks()
Dim strSQL As String
Dim qry As DAO.QueryDef

‘ — 動的SQLの組み立て —
strSQL = “SELECT FROM T_Books WHERE ”

‘ テキストボックスの値を SafeSQLStr に通すだけ!
‘ ユーザーが「O’Reilly」と入力しても、関数が内部で自動処理してくれます。
strSQL = strSQL & “BookName = ” & SafeSQLStr(Me.txtSearch.Value) & ” ”

‘ さらに、もしあいまい検索(LIKE)にしたい場合もこの関数が使えます!
‘ 例: LIKE ‘%O”Reilly%’ のように前後に % を挟む場合
‘ strSQL = strSQL & “AND Memo LIKE ‘%” & Replace(Me.txtSearch.Value, “‘”, “””) & “%'”

‘ クエリ定義(QueryDef)オブジェクトを更新して実行
Set qry = CurrentDb.QueryDefs(“Q_DynamicSearch”)
qry.SQL = strSQL
qry.Close
Set qry = Nothing

‘ フォームのデータソースを更新して結果を表示
Me.RecordSource = “Q_DynamicSearch”
Me.Requery

MsgBox “検索が完了しました!”, vbInformation, “成功”
End Sub

どうでしょうか? SQL文の中に無理やり `’` と `&` を複雑に組み合わせる必要がなくなパッと見のコードが劇的に美しく、読みやすくなったのが分かるはずです。

—

5. 伝説のアーキテクトからのメッセージ

プログラミング初学者のうちは、「動けばいいや」と画面の入力値をそのままSQLに直結させがちです。しかし、実際の業務システムでは、ユーザーは開発者が想像もしないような文字を入力します(絵文字や全角スペース、そして今回扱ったシングルクォーテーションなど)。

今回紹介した `SafeSQLStr` のような「入力値を安全にサニタイズ(無害化)する部品」を一つ持っておくだけで、将来発生する謎のバグや、ユーザーからの「システムが急に止まった!」という悲鳴を未然に防ぐことができます。

地味ですが、こうした細部へのこだわりこそが、プロとアマを分ける境界線です。
ぜひあなたのAccessアプリにもこの関数を組み込んで、ワンランク上の安定感を手に入れてくださいね。応援しています!

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