Accessのリンクテーブル管理:Application.FileSearchの亡霊を捨て、FSOで「盤石な」再接続を実現する
Access開発の現場で、バックエンド(BE)ファイルの移動に伴う「リンクテーブル切れ」に頭を抱えたことはないだろうか?
かつては `Application.FileSearch` がこの手の自動化の代名詞だった。しかし、Access 2007以降、その存在は歴史の彼方へ消えた。今なお古いコードを継承し、不安定な動的パス指定で疲弊しているエンジニア諸君に告ぐ。「ファイル操作は常にFSO(FileSystemObject)に委ねろ」。
本稿では、リンクテーブルの再接続という、一見単純だが奥が深いタスクを通じ、プロダクションレベルの堅牢な設計思想を叩き込む。
—
1. なぜ「雑な再接続」が現場を壊すのか
多くの開発者が陥る失敗は、「全リンクテーブルをループして、強制的にパスを書き換える」という乱暴なアプローチだ。
- パスの不整合: BEファイルが存在しないパスをセットしてしまい、次回起動時に地獄を見る。
- 非効率なループ: リンク先が正しいか確認せず、すべての接続をリフレッシュすることで、ネットワーク負荷を無駄に増大させる。
- 例外処理の欠如: 権限エラーや排他制御時のフリーズを考慮していない。
我々が目指すべきは、「接続先が正しいか検証し、必要であれば安全に書き換え、エラーがあれば即座にログを残して停止する」というトランザクション的な思考だ。
—
2. 実装の要:FSOを活用した堅牢な再接続ロジック
以下のコードは、バックエンドファイルの存在を確実に確認し、リンクテーブルの接続先を更新するモジュールだ。単なるコピペコードではない。実運用での耐性を高めるための「守り」を実装している。
Option Compare Database
Option Explicit
‘ 参照設定: Microsoft Scripting Runtime (scrrun.dll) を推奨
‘ 参照設定なしでも動くよう、あえてLate Bindingで記述(配布時のトラブルを避けるため)
Public Sub ReconnectLinkedTables(ByVal newBackendPath As String)
Dim fso As Object
Dim tdf As DAO.TableDef
Dim db As DAO.Database
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set db = CurrentDb
‘ 1. BEファイルの存在確認(ここを怠るとリンクが壊れる)
If Not fso.FileExists(newBackendPath) Then
MsgBox “指定されたバックエンドファイルが見つかりません: ” & vbCrLf & newBackendPath, vbCritical
GoTo Cleanup
End If
‘ 2. リンクテーブルのみを抽出し、パスを更新
For Each tdf In db.TableDefs
‘ 接続文字列(Connect)が空でない=リンクテーブルであると判定
If Len(tdf.Connect) > 0 Then
‘ パスのみを置き換える(MS Access;DATABASE=…)
tdf.Connect = “;DATABASE=” & newBackendPath
On Error Resume Next
tdf.RefreshLink ‘ ここで接続テストを行う
If Err.Number <> 0 Then
Debug.Print “エラー: ” & tdf.Name & ” の再接続に失敗しました。”
Else
Debug.Print “成功: ” & tdf.Name
End If
On Error GoTo 0
End If
Next tdf
MsgBox “リンクテーブルの再接続が完了しました。”, vbInformation
Cleanup:
Set fso = Nothing
Set db = Nothing
End Sub
—
3. アーキテクトの視点:なぜこのコードが「強い」のか
① Late Binding(遅延バインディング)の採用
`Dim fso As FileSystemObject` とせず `Object` 型で定義し、`CreateObject` を使用している。これにより、クライアントPCの参照設定の不一致による「コンパイルエラー」を回避できる。配布ツールとしての安定性はここにある。
② `tdf.RefreshLink` の重要性
多くのコードが単に `Connect` 文字列を代入して終わる。しかし、それは「接続できたつもり」になっているだけだ。`RefreshLink` を呼ぶことで、実際にAccessがBEファイルと握手を交わす。この瞬間のエラーをハンドリングすることこそが、堅牢なシステムの証だ。
③ 責務の分離
このモジュールには「パスを指定する」というロジックは含めていない。UI(フォームのテキストボックス等)からパスを受け取り、この関数を呼び出すという「インターフェースとロジックの分離」を意識せよ。
—
4. さらなる高みを目指すなら
実戦では、BEファイルが複数ある場合や、パスワード付きMDBへの接続など、考慮すべき点は増える。だが、まずはこのベースを完璧に理解してほしい。
次に実装すべきは、「現在のリンク先と、新しいパスを比較し、一致していれば再接続をスキップする」という最適化ロジックだ。不要なディスクI/Oを削ぎ落とすことこそ、真のプロフェッショナルの仕事である。
コードは「書く」ものではなく「構築する」ものだ。一つひとつの命令の重みを理解し、Accessの挙動を支配せよ。君のツールが、ユーザーの業務を止めることは二度とないはずだ。
