こんにちは!Accessの業務自動化、進んでいますか?
「ネットワークの共有フォルダの場所が変わったら、Accessのリンクテーブルが全部切れてしまった……」
「朝出社したら『パスが見つかりません』エラーが出て、全ユーザーから泣きつきされた……」
Accessでマルチユーザー環境やバックエンド・フロントエンド分離のシステムを運用していると、こんな絶望的な朝に一度は直面したことがあるのではないでしょうか。一つひとつ手作業でリンクマネージャを開いて繋ぎ直すなんて、エンジニアの仕事ではありませんよね。
今回は、Access起動時に自動でリンクテーブルの接続先を検証し、切れていれば一瞬で自動修復する「要塞級の自動修復メカニズム」を一緒に作っていきましょう。
ここをクリアすれば、Access VBAのオブジェクトモデルとファイル操作の基本はバッチリです!優しく、しかし本質的なところまで徹底的に解説していきますね。
—
なぜリンク切れが起きるのか?Accessの裏側を覗いてみよう
まず、Accessの「リンクテーブル」がどういう状態にあるかを知ることから始めましょう。
通常のテーブルはAccessファイル(.accdb)の中にデータもデザインも入っていますが、リンクテーブルは「中身のデータは別の場所(サーバーの共有フォルダなど)にあるデータベースに置いてあって、今のファイルからは『看板(リンク)』だけが見えている状態」です。
この看板には、「どこに本体があるか」という住所(接続文字列:Connectプロパティ)がしっかり書き込まれています。
ネットワークのドライブ割り当てが変わったり、共有フォルダのサーバー名が変わったりすると、この住所が無効になり、Accessは「あれ、データがないぞ!」とパニックを起こしてリンク切れエラーを吐くわけです。
—
解決の鍵:`CurrentDb` と `TableDefs` オブジェクト
VBAでこの問題を解決するために登場するのが、Accessの心臓部であるDAO(Data Access Objects)という仕組みです。
- `CurrentDb`: 今まさに開いているAccessデータベースそのものを指すオブジェクト。
- `TableDefs`: データベースの中にある「すべてのテーブルの設計図(定義)」が集まったコレクション。
この `TableDefs` の中から「リンクテーブルだけ」を抜き出し、それぞれの接続先(Connect)をプログラムから書き換えてあげれば、自動修復の完成というわけです。
—
実装コード:起動時に走る「自動修復ルーチン」
それでは、実際のコードを見てみましょう。
このコードは、Accessを起動したときに一番最初に動くフォーム(あるいはAutoExecマクロから呼び出すプロシージャ)に組み込むことを想定しています。
Option Compare Database
Option Explicit
‘ ====================================================================
‘ テーマ:リンクテーブルの接続文字列を起動時に自動修復する
‘ 解説 :指定したバックエンドファイルの存在確認を行い、
‘ リンク切れしているテーブルの接続先を動的に再設定します。
‘ ====================================================================
Public Sub AutoRepairLinkTables()
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim targetBackendPath As String
Dim repairedCount As Long
On Error GoTo ErrorHandler
‘ 1. 正しいバックエンド(データ側)のパスを定義する
‘ ※実際の運用環境に合わせて、UNCパス(\\サーバー名\…)を指定するのが鉄則です!
targetBackendPath = “\\公司的なサーバー\SharedFolder\Database\Backend_be.accdb”
‘ 2. バックエンドファイル自体が存在するかを事前にチェック
If Dir(targetBackendPath) = “” Then
MsgBox “致命的なエラー: データ保存先のサーバーに接続できません。” & vbCrLf & _
“ネットワーク接続を確認してください。” & vbCrLf & _
“パス: ” & targetBackendPath, _
vbCritical, “起動時リンク修復”
Exit Sub
End If
‘ 3. 現在のデータベースオブジェクトを取得
Set db = CurrentDb
repairedCount = 0
‘ 4. すべてのテーブル定義をループして、リンクテーブルを探す
For Each tdf In db.TableDefs
‘ Connectプロパティに文字列が入っているものは「リンクテーブル」
If Len(tdf.Connect) > 0 Then
‘ 5. 接続先を新しい(正しい)パスに強制的に書き換える
‘ ※AccessのリンクテーブルのConnect書式は “MS Access;DATABASE=パス” となります
tdf.Connect = “;DATABASE=” & targetBackendPath
‘ 6. 変更をテーブルに反映(リフレッシュ)させる
tdf.RefreshLink
repairedCount = repairedCount + 1
End If
(Next tdf)
‘ 7. 完了メッセージ(実運用ではログ出力だけにしてもスマートです)
If repairedCount > 0 Then
MsgBox “リンクテーブルの自動修復が完了しました。(修復数: ” & repairedCount & “件)”, _
vbInformation, “システム起動”
End If
NormalExit:
‘ オブジェクトの解放(メモリリークを防ぐプロの作法です)
Set tdf = Nothing
Set db = Nothing
Exit Sub
ErrorHandler:
MsgBox “リンクの修復中に予期せぬエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“エラー内容: ” & Err.Description, _
vbCritical, “エラー”
Resume NormalExit
End Sub
—
コードの注目ポイントと「初心者がハマりやすい罠」
このコードには、現場で培ったノウハウがギュッと詰まっています。いくつか重要なポイントを解説しますね。
① `Dir` 関数による事前チェックの重要性
いきなり書き換えを行うのではなく、`Dir(targetBackendPath)` でファイルが本当に存在するかをチェックしています。もしネットワークが完全に切れている状態で書き換えを行おうとすると、VBAが重いフリーズを起こしたり、予期せぬ実行時エラーで強制終了したりします。優しさの第一歩は「疑うこと」から始まります。
② UNCパス(ネットワークパス)を使うべし
`”C:\Users\…\Desktop\…”` のようなローカルパスやドライブ文字(`Z:\…`)を接続先に指定すると、PCごとの割り当て違いで大事故になります。必ず `\\servername\share\…` という UNCパス を指定するのが、ネットワーク運用における鉄則です。
③ オブジェクトの解放(`Set … = Nothing`)
VBA初学者が忘れがちなのが、`CurrentDb` や `TableDefs` で生成したオブジェクトのメモリ解放です。これをサボると、Access内部にゴミが残り、長期間運用しているうちに動作が不安定になります。プログラミングの美しさは、後片付けの美しさでもあるのです。
—
さらに現場を頑健にするためのヒント
もし、「バックエンドファイルが複数あるよ!」という複雑なシステムの場合はどうすればいいでしょうか?
そんなときは、`tdf.Connect` の中身を分解し、「古いサーバー名が含まれている場合だけ新しいサーバー名に置換する(`Replace関数`を使用する)」というアプローチをとると、さらに柔軟な修復ツールに進化させることができます。
ここをクリアできれば、もう「リンク切れ対応」で冷や汗をかく必要はありません。Accessが勝手に自己修復してくれる、まるで生き物のような堅牢なシステムがあなたの手で作れるようになります。
ぜひ、次の開発案件から取り入れてみてくださいね。応援しています!
