【テクニカル・上級編】Application.GetOptionで「名前の自動修正」をVBAで一時的に無効化するリスク回避 – Access VBA解析バイブル

スポンサーリンク

「名前の自動修正」という名の爆弾を解体せよ:Access肥大化と戦うアーキテクトの矜持

Accessを「単なるデスクトップDB」と侮るなかれ。数十年もの間、数多の基幹システムを支え続けてきたこのエンジンは、一見すると親切心に満ち溢れている。だが、その親切心が時にシステムを死に至らしめることを、君は知っているか。

今日のテーマは「名前の自動修正(Name AutoCorrect)」だ。
この機能は、テーブルのフィールド名やクエリ名を変更した際、参照先を連鎖的に追跡・修正してくれる。初心者がGUIで遊ぶには便利だが、大規模なトランザクションや一時テーブルの動的生成を繰り返すシステムにとっては、まさに「見えないところでDBを破壊する」時限爆弾に他ならない。

今回は、この機能をVBAで制御し、システムの「恒常的な安定」を勝ち取るための極限の知見を授けよう。

1. なぜ「名前の自動修正」は悪魔の機能なのか

Accessが「名前の自動修正」を有効にしているとき、内部では「名前の自動修正ログ(Name AutoCorrect Log)」という隠しシステムテーブルが膨れ上がる。

  • 肥大化の正体: 膨大なレコードを出し入れするたび、Accessはこのログを更新しようとする。これがデータベースのフラグメンテーションを加速させ、 `.accdb` を短期間で肥大化させる主因だ。
  • 整合性の崩壊: 中規模以上の開発現場において、この機能が意図しないタイミングで誤作動を起こし、複雑なクエリのパスがズレたときの絶望を知っている者は多いはずだ。

プロフェッショナルであれば、この機能は「開発中はON、デプロイ後の運用実行時はOFF」が鉄則である。

2. VBAによる完全制御:Application.GetOption と SetOption

Accessのオプション設定は、`Application.GetOption`(取得)と `Application.SetOption`(設定)で制御する。ここで重要なのは、「処理の開始前に状態を退避させ、終了後に必ず元の状態へ戻す」という例外処理の基本だ。

‘ —————————————————————————
‘ 処理名:ExecuteSafeTransaction
‘ 概要:名前の自動修正を一時的に無効化し、安全に処理を実行する
‘ —————————————————————————
Public Sub ExecuteSafeTransaction()
Dim originalState As Boolean

‘ 1. 現在の「名前の自動修正」設定を退避
‘ 0: 追跡しない / 1: 追跡する
originalState = Application.GetOption(“Track Name AutoCorrect Info”)

On Error GoTo ErrorHandler

‘ 2. 無効化(肥大化を抑制するため)
If originalState = True Then
Application.SetOption “Track Name AutoCorrect Info”, False
End If

‘ 3. ここに高負荷なテーブル操作やDDL処理を記述
Call PerformHeavyOperation

Cleanup:
‘ 4. 必ず元の状態へ復帰させる(最重要)
Application.SetOption “Track Name AutoCorrect Info”, originalState
Exit Sub

ErrorHandler:
Debug.Print “Error: ” & Err.Description
Resume Cleanup
End Sub

3. シニアエンジニアが意識すべき「メモリの流儀」

上記コードを見て、「なぜわざわざ `originalState` を保存するのか?」と疑問に思う若手もいるかもしれない。

システム運用において、「自分のコードが、元の環境を汚さないこと」は美学だ。特にCOMオブジェクトとして外部からAccessを操作する際、あるいは複数の開発者が入り乱れるレガシー環境では、状態の破壊は致命的な競合を生む。

オブジェクトの明示的解放とガベージコレクション

VBAは参照カウンタ方式でメモリを管理しているが、`CurrentDb` や `DAO.Recordset` を多用する処理では、明示的な解放を怠ると解放のタイミングが遅延し、メモリリークを誘発する。

Dim db As DAO.Database
Dim rs As DAO.Recordset

Set db = CurrentDb
Set rs = db.OpenRecordset(“YourTable”, dbOpenDynaset)

‘ 処理…

‘ 厳格な解放順序
rs.Close: Set rs = Nothing
Set db = Nothing ‘ CurrentDbはキャッシュされるが、明示的解放はバッドプラクティスではない

4. 極限環境でのさらなる最適化:Windows APIの活用

もし君が「レコード単位の更新」を繰り返すような、非効率なコードを捨てきれない状況にいるのであれば、APIを介して `CompactDatabase` を自動化するルーチンを組み込むべきだ。

しかし、真のアーキテクトは「後始末」ではなく「汚さない設計」を好む。
`名前の自動修正`を切ることは、そのための第一歩に過ぎない。

最後に

Accessは、適切に飼いならせば、これほど強力な武器はない。
「便利機能」に身を委ねるのではなく、エンジニア自らがその挙動を掌握する。その執念が、数年後の「壊れないシステム」という成果物として現れるのだ。

君のコードが、今日もどこかで軽快に動いていることを願う。健闘を祈る。

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