【入門編】QueryDefの「再利用」がもたらすAccessファイル肥大化の防止策 – Access VBA解析バイブル

スポンサーリンク

Accessが「謎の肥大化」で悲鳴を上げる前に。QueryDefの真実と、賢い管理術

こんにちは。現場でAccessと格闘している皆さん、お疲れ様です。

Accessを使っていると、ふとこんな現象に遭遇しませんか?
「最初は軽快だったのに、なぜかファイルサイズが急激に膨れ上がった」「動的SQLをバリバリ書いていたら、動作が重くなった」。

実はこれ、「QueryDef(クエリ定義)」の無駄な生成と破棄が原因であることがほとんどです。今日は、Accessを「ただ動くもの」から「プロ仕様の堅牢なシステム」へ引き上げるための、QueryDef管理の極意を伝授します。

—

1. なぜ「動的SQL」はAccessを太らせるのか?

皆さんがVBAでSQLを組み立てる際、よくやるのがこれではないでしょうか。

‘ 悪い例:毎回新しいクエリを作って使い捨てている
CurrentDb.CreateQueryDef(“tempQuery”, “SELECT FROM T_Sales WHERE SalesDate = #” & strDate & “#”)

これを繰り返すと、Accessの内部では「名前のない一時的なクエリ定義」や「ゴミクエリ」がシステムテーブルの奥深くに蓄積されていきます。Accessは、たとえ削除したつもりでも、内部のインデックスやメタデータが完全には整理されず、ファイルの肥大化(いわゆる「お化けデータ」の蓄積)を招くのです。

—

2. 極限の解決策:QueryDefを「使い回す」

解決策はシンプルです。「毎回作る」のではなく、「1つの枠を用意して、中身だけを書き換える」こと。これがQueryDefのライフサイクル管理の基本です。

実践的コード:クエリ定義の更新管理フロー

以下は、既存のクエリ定義があれば更新し、なければ新規作成する、という「再利用」のための鉄板コードです。

Public Sub UpdateQueryDefinition(queryName As String, strSQL As String)
Dim db As DAO.Database
Dim qdf As DAO.QueryDef

Set db = CurrentDb

‘ 既に同じ名前のクエリが存在するかチェック
If QueryExists(queryName) Then
‘ 存在する場合は、既存のQueryDefをセットしてSQLを書き換える
Set qdf = db.QueryDefs(queryName)
qdf.SQL = strSQL
Else
‘ 存在しない場合のみ新規作成
Set qdf = db.CreateQueryDef(queryName, strSQL)
End If

‘ 最後に参照を解放(メモリの断片化を防ぐための必須作法)
Set qdf = Nothing
Set db = Nothing
End Sub

‘ クエリが存在するかを確認するヘルパー関数
Private Function QueryExists(queryName As String) As Boolean
Dim qdf As DAO.QueryDef
QueryExists = False
For Each qdf In CurrentDb.QueryDefs
If qdf.Name = queryName Then
QueryExists = True
Exit For
End If
Next qdf
End Function

—

3. ここがプロの視点:なぜこの手法が「正解」なのか

このコードのポイントは3つあります。

1. システム負荷の低減: `CreateQueryDef`を無闇に呼ばないことで、データベースエンジンのメタデータ更新を最小限に抑えています。
2. 型定義の明確化: `DAO.QueryDef`を明示的に使用することで、Accessのクエリエンジンに最適な実行計画を立てさせることができます。
3. オブジェクトの解放: `Set qdf = Nothing`。ここを怠る初心者が非常に多いです。VBAでは、使い終わったオブジェクトを明示的にメモリから解放してあげるのが「大人のマナー」です。

—

4. 陥りやすい罠:パラメータークエリとの併用

もし、より高度なセキュリティ(SQLインジェクション対策)を求めるなら、`strSQL`を文字列連結で作るのではなく、パラメータークエリを使いましょう。

‘ パラメータークエリの例
Set qdf = db.QueryDefs(“myQuery”)
qdf.Parameters(“[Forms]![frmMain]![txtDate]”) = Me.txtDate.Value
‘ これならSQLを直接操作せず、安全かつ高速に実行可能!

パラメータークエリをあらかじめ定義しておき、VBAからは「値を渡すだけ」にすれば、SQLの再パースが発生せず、パフォーマンスが劇的に向上します。

—

最後に:Accessと長く付き合うために

「コードが動くこと」は通過点に過ぎません。「システムが疲弊せずに動き続けること」こそが、エンジニアの腕の見せ所です。

今日から、クエリを作るたびに「これは再利用できないか?」と自問してみてください。その意識一つで、あなたの書くAccessコードは、数年後もメンテナンス可能な「資産」に変わります。

ここをクリアすれば、皆さんはもう初学者ではありません。自信を持って、より良いシステムを構築してくださいね。応援しています!

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