【入門編】SQL ServerのビューをQueryDef経由で参照する際の「パススルー」最適化設定 – Access VBA解析バイブル

スポンサーリンク

こんにちは! Access VBAの世界へようこそ。
マクロの記録ボタンを押すだけの世界から一歩抜け出し、「自分の手でシステムをコントロールしたい」と願うあなたへ、今日はとてもエキサイティングな技術をお伝えします。

今回取り上げるのは、「SQL ServerのビューをQueryDef経由で参照する際の『パススルー』最適化設定」です。

なんだか呪文のような名前が並びましたね。「パススルー? クエリデフ? なんそれ?」と思った方も大丈夫。ここをクリアすれば、あなたのAccessアプリは見違えるほど高速化し、プロのエンジニアが作るシステムと同等のパフォーマンスを手に入れることができます。

基礎から本質まで、優しく、そして深く噛み砕いて解説していきますね。ここをクリアすれば、Access VBAの基本はバッチリですよ!

—

1. なぜ「パススルー」が必要なのか?(本質を知る)

皆さんは普段、Accessのクエリデザイナでテーブルを結合したり、条件を指定してデータを抽出していると思います。
Accessの裏側には「ACE(またはJet)エンジン」という小さなデータ処理の頭脳がいます。通常、AccessからSQL Serverのデータを見るとき、Access君はこんな無茶をしています。

1. 「ねえ、SQL Serverさん、そのビューのデータ全部こっちによこして!」(SQL Serverから数百万件のデータをネットワーク経由でゴッソリ持ってくる)
2. 「ふー、重かった。じゃあ、この中から私の条件に合うやつだけ抽出するか…」(Access君が自分の非力なパソコンのメモリ上で一生懸命フィルターをかける)

…お分かりでしょうか? ネットワークは渋滞し、あなたのPCのメモリはパンク寸前になりますよね。これが「遅い」と感じる根本的な原因です。

パススルー・クエリという「直行便」

これに対する解決策がパススルー・クエリです。
これは、「Accessの頭脳を通さず、SQL Serverに直接SQL文を投げつけて、向こうの超パワフルなサーバーに計算を全部お任せし、結果だけを静かに受け取る」という、いわば直行便です。

SQL Server側で絞り込みや集計を完結させるため、ネットワークを流れるデータ量は最小限になり、処理スピードは劇的に向上します。これをVBAで動的に生成・制御できるようになると、Accessの限界を軽々と突破できるようになります。

—

2. QueryDefとパススルーの基本構造

Accessでパススルー・クエリを扱う主役が `QueryDef`(クエリ定義)オブジェクト です。

通常、Accessのクエリは「デザイン画面」で作りますが、VBAを使うと「コードで一瞬にしてクエリを作り、実行し、終わったら消す」という神業ができます。

パススルー・クエリを機能させるための「絶対条件」は以下の2つです。

1. 接続文字列(Connectプロパティ)の設定:どのSQL Serverの、どのデータベースに繋ぐのかを教える。
2. ReturnsRecordsプロパティの設定:そのSQLが「データを返すもの(SELECT)」か「データを返さないもの(UPDATEやDELETE)」かを指定する。

—

3. 実践!動的パススルー・クエリ生成コード

それでは、現場でそのままコピペして使える実用的なコードを見ていきましょう。
画面上のフォームで指定した「抽出日付」などの条件を組み込み、SQL Serverのビューから高速にデータを取得するVBAコードです。

Sub ExecuteSqlServerPassThrough()
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim qryName As String
Dim strSQL As String
Dim connStr As String
Dim targetDate As String

‘ クエリの名前(一時的に作成・利用する名前)
qryName = “temp_PassThrough_Query”

‘ 1. 接続文字列の定義(ODBCドライバ経由でSQL Serverに接続)
‘ ※環境に合わせて Server, Database, UID, PWD を書き換えてください
connStr = “ODBC;DRIVER={ODBC Driver 17 for SQL Server};” & _
“SERVER=your_server_name;DATABASE=your_db_name;” & _
“Trusted_Connection=Yes;” ‘ 統合Windows認証の場合
‘ ※SQL Server認証の場合は “UID=username;PWD=password;” を追加してください

‘ 2. 画面から条件を取得する想定(例として固定値)
targetDate = “2023-10-01”

‘ 3. SQL Server側に直接投げるSQL文を組み立てる
‘ ★ポイント:ここでの構文は、Access用ではなく「SQL Server用(T-SQL)」で書くこと!
strSQL = “SELECT OrderID, CustomerID, OrderDate, TotalAmount ” & _
“FROM vw_MonthlyOrders ” & _
“WHERE OrderDate >= ‘” & targetDate & “‘ ” & _
“ORDER BY OrderDate DESC;”

Set db = CurrentDb

‘ 4. 既存の同名クエリがあれば削除しておく(エラー回避のお作法)
On Error Resume Next
db.QueryDefs.Delete qryName
On Error GoTo 0

‘ 5. QueryDefオブジェクトを新規作成
Set qdf = db.CreateQueryDef(qryName)

‘ 6. 【超重要】パススルーの設定を行う
With qdf
.Connect = connStr ‘ 接続先の指定
.SQL = strSQL ‘ 実行するT-SQLの指定
.ReturnsRecords = True ‘ データを返すクエリ(SELECT)の場合はTrue
End With

‘ 7. フォームやレポートのデータソースに割り当てる、または開く
‘ 例:このクエリ結果を元に処理を行う、あるいは画面に表示する
DoCmd.OpenQuery qryName

‘ 後片付け
Set qdf = Nothing
Set db = Nothing

MsgBox “パススルー・クエリによる高速処理が完了しました!”, vbInformation
End Sub

コードの解説と「知見」

  • T-SQLの方言に注意:パススルー・クエリの中身は、AccessのSQL(“の代わりに`%`を使う等)ではなく、SQL Serverの言葉(T-SQL)で記述する必要があります。日付の囲み文字(`’`)や組み込み関数もSQL Serverの仕様に従います。
  • クエリのクリーンアップ:動的にQueryDefを作るときは、ゴミが溜まらないように使い終わったら削除するか、既存のものを上書きする設計にしましょう。

—

4. 現場でよくある「罠」とエラー回避の極意

初学者がこのパススルーに挑むとき、必ずと言っていいほどハマるポイントがいくつかあります。先輩エンジニアからのアドバイスとして受け取ってください。

罠その1:パスワードが丸見えになる恐怖

接続文字列に `UID=sa;PWD=secretPassword;` のように平文でパスワードを書くと、セキュリティ上非常に危険です。
解決策:社内システムであれば、可能な限り `Trusted_Connection=Yes;`(Windows認証)を使い、個別のパスワードをコード内に書かない工夫をしましょう。どうしてもSQL Server認証が必要な場合は、接続文字列の保存を許可しない設定(`SavePassword = False`)などに気を配りましょう。

罠その2:「ODBCドライバが見つかりません」エラー

新しいPCや環境で動かしたときによく起きます。コード内の `ODBC Driver 17 for SQL Server` 部分が、そのPCに入っているドライバと一致していないとエラーになります。
解決策:PCの「ODBC データ ソース アドミニストレーター」を開き、インストールされているドライバ名を確認してコードの `DRIVER={…}` 部分を合わせるか、汎用的な `ODBC Driver 18` や古い `SQL Server` ドライバを指定します。

罠その3:ビューのパラメータ化で悩む

「VBAからパラメータ(条件値)を渡したいのに、パススルーだとクエリパラメータ(`[Forms]![1]![TextBox]`など)が使えない!」という壁にぶつかります。
解決策:パススルー・クエリの `.SQL` プロパティはただの「文字列」です。上のサンプルコードのように、VBA側で変数を使ってSQL文字列を組み立ててから代入する(動的SQL生成)のが、パススルーを使いこなすための王道にして最強のテクニックです。

—

まとめ

いかがでしたでしょうか?

  • Accessのエンジンに無理をさせず、SQL Serverに仕事を丸投げする「パススルー」
  • VBAの `QueryDef` を使って、その場でSQLを組み立てて実行するダイナミックな手法

この2つをマスターすれば、あなたの作るAccessアプリは「重くて使い物にならないお荷物」から、「爆速でデータを捌く頼れるフロントエンド・システム」へと生まれ変わります。

最初は接続文字列の書き方などで少し戸惑うかもしれませんが、一度動く型を作ってしまえば、どんな巨大なSQL Serverのビューでも自由自在に手なずけられるようになります。

ぜひ、あなたの開発現場でも試してみてくださいね。応援しています!

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