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)」をメモリ上で展開することを検討せよ。
物理ファイルに書き込まず、メモリ上にデータを保持する手法を学べば、あなたの作るツールは驚くほど軽量で、かつプロフェッショナルな挙動を示すようになる。
「動けばいい」という段階は卒業しよう。「いかに美しく、いかに爪痕を残さず終了するか」。それこそが、真の業務自動化エンジニアの嗜みだ。
