【実務・中級編】フォームの「Unload」イベントで実行する、一時的なリソース(一時テーブル・クエリ)のクリーンアップ – Access VBA解析バイブル

スポンサーリンク

Accessの「ゴミ屋敷化」を防げ:Unloadイベントによるリソース管理の極意

Access開発において、多くのエンジニアが見落としがちなのが「オブジェクトのライフサイクル管理」だ。

「とりあえず動くから」と、処理のたびに一時テーブルを作成し、そのまま放置していないだろうか。Accessはバックエンド(accdb/accde)が物理的に肥大化する性質を持つ。放置された一時オブジェクトは、単なるストレージの無駄ではない。インデックスの断片化、クエリプランの非効率化、そして最悪の場合はデータベース破損のトリガーとなる「時限爆弾」だ。

今回は、フォームの`Unload`イベントを起点とした、極めて堅牢かつクリーンなリソース破棄のアーキテクチャを伝授する。

1. なぜ「Unload」なのか?「Close」との決定的な違い

VBAにおいて、フォームを閉じる際にイベントが発火する順序は以下の通りだ。
1. Unload: 閉じようとしている(キャンセル可能)
2. Deactivate: フォーカスを失う
3. Close: 完全に閉じた後

多くの初心者は`Close`イベントに終了処理を書くが、これは設計ミスだ。`Close`の時点では、すでにフォームのインスタンスはメモリから解放されかけており、予期せぬエラーやオブジェクトの残骸が生じるリスクがある。「リソースのクリーンアップは、アンロードのプロセスが確定した段階(Unload)で完了させる」のが鉄則である。

2. 堅牢なクリーンアップ・アーキテクチャ

単に `DoCmd.DeleteObject` を並べるだけでは不十分だ。オブジェクトが存在しない場合にエラーで止まるコードは、プロのコードとは呼べない。

実装のポイント

  • エラーハンドリングの徹底: オブジェクトの有無を事前に判定するか、エラーを黙殺(Resume Next)するガード節が必要。
  • 明示的な開放: データベースエンジンにクリーンアップを促すため、`CurrentDb` を明示的に再参照する。

プロダクションコード例

以下は、フォームの終了時に「tmp_」で始まる作業用テーブルを安全に破棄する汎用的なコードだ。

Private Sub Form_Unload(Cancel As Integer)
On Error GoTo Err_Handler

‘ 終了処理の実行
Call CleanupTemporaryObjects

Exit Sub

Err_Handler:
‘ 予期せぬエラーはログ出力やデバッグ用に記録するが、
‘ アプリを止めるべきではないので必要に応じて対応
Debug.Print “クリーンアップエラー: ” & Err.Description
End Sub

”’

”’ 一時オブジェクトを安全に削除するプロシージャ
”’

Private Sub CleanupTemporaryObjects()
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim qdf As QueryDef

Set db = CurrentDb

‘ 1. 一時テーブルの削除
‘ 削除対象をループで回し、安全に削除する
For Each tdf In db.TableDefs
If Left(tdf.Name, 4) = “tmp_” Then
DoCmd.DeleteObject acTable, tdf.Name
End If
Next tdf

‘ 2. 一時クエリの削除
For Each qdf In db.QueryDefs
If Left(qdf.Name, 4) = “tmp_” Then
DoCmd.DeleteObject acQuery, qdf.Name
End If
Next qdf

‘ 重要: データベースの断片化を防ぐため、必要に応じて最適化を考慮するが
‘ 頻繁な最適化はパフォーマンスを落とすため、規模に応じて検討すること。

Set db = Nothing
End Sub

3. なぜこの設計が「最強」なのか

このコードが他の記述と一線を画す理由は、「疎結合な命名規則による管理」にある。

1. 命名規則の強制: `tmp_` というプレフィックスをルール化することで、コードの可読性が飛躍的に向上する。どのテーブルが使い捨てか、一目で判別できる。
2. DAOオブジェクトの活用: `CurrentDb` を変数にキャッシュすることで、何度も `CurrentDb` を呼び出すことによるオーバーヘッドを回避している。これは数千行規模のシステムでは無視できないパフォーマンス改善だ。
3. 保守性: もし今後、削除対象が増えても `CleanupTemporaryObjects` 内のロジックを修正するだけでいい。各フォームに個別の削除コードを散乱させるのは、メンテナンス性の死を意味する。

4. エンジニアへの警告:DBを「ゴミ箱」にするな

Accessのバックエンドが肥大化し、「動作が重い」「よく落ちる」と嘆く現場の多くは、この「リソースの持ち逃げ」が原因だ。

  • 一時テーブルは必ず使い捨てること。
  • 複雑な処理の結果を保存したいなら、一時テーブルではなく「一時的なレコードセット(DAO.Recordset)」をメモリ上で展開することを検討せよ。

物理ファイルに書き込まず、メモリ上にデータを保持する手法を学べば、あなたの作るツールは驚くほど軽量で、かつプロフェッショナルな挙動を示すようになる。

「動けばいい」という段階は卒業しよう。「いかに美しく、いかに爪痕を残さず終了するか」。それこそが、真の業務自動化エンジニアの嗜みだ。

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