【入門編】ADOの接続エラーをログファイルに書き出す:運用保守のためのエラーハンドリング – Access VBA解析バイブル

スポンサーリンク

こんにちは!現場でバリバリ活躍できるAccessエンジニアを目指して、今日も一歩ずつ進んでいきましょう。

マクロの記録から一歩抜け出し、「自分でコードを書いてシステムをコントロールしたい!」そう思ったとき、最初に立ちはだかる大きな壁が「外部データベースやファイルとの接続エラー」です。

特に、AccessからSQL ServerやOracle、あるいは別のAccessファイルへ「ADO(ActiveX Data Objects)」を使って接続するとき、ネットワークの瞬断やパスワードの変更などで突然接続が失敗することがあります。

「なんか動かないんですけど!」というユーザーからの問い合わせに、エラー番号も分からず頭を抱える……。そんな運用保守の地獄からあなたを救い出す、「ADO接続エラーをFSO(FileSystemObject)でログに記録する堅牢なエラーハンドリング」の極意を授けましょう。

ここをクリアすれば、あなたの書くVBAは「おもちゃのスクリプト」から「プロのエンタープライズシステム」へと劇的に進化しますよ。

—

なぜ、ADOの接続エラーは厄介なのか?

Access VBAには、標準で用意されている「DAO(Data Access Objects)」という強力なデータアクセス手段があります。Access内部のテーブルを触るならDAOで十分です。

しかし、社内の別サーバーにあるデータベースに繋いだり、高度な非同期処理を行ったりする場合にはADOが主役になります。

ここで問題になるのが、「接続エラーの原因が多岐にわたる」という点です。

  • サーバーのIPアドレスが変わった
  • 接続文字列(ConnectionString)のスペルミス
  • データベースのサービスが停止している
  • 認証情報(ユーザー名・パスワード)の有効期限切れ

これらが起きたとき、VBAのデフォルトのままだと、ユーザーの画面に冷たいエラーダイアグラム(実行時エラー)がポキッと表示され、現場は大パニックです。「何時何分に、どこで、どんなエラーが出たのか」を開発者が後から追えない状態は、運用保守において最大の悪です。

だからこそ、「エラーを美しく捕捉し、詳細をログファイルに書き出す仕組み」を最初から組み込んでおく必要があるのです。

—

現場で即戦力になる!ADO接続&ログ出力の実装コード

百聞は一見に如かず。まずは、エラーハンドリングとログ出力を完璧に網羅した実用コードを見てください。

このコードは、モジュールに貼り付けてそのまま実戦で使えるように設計しています。

Option Explicit

‘ =========================================================================
‘ テーマ: ADO接続エラーのFSOを用いたログ出力と堅牢なエラーハンドリング
‘ 著者の哲学: 「エラーを隠すな、記録して未来の自分とユーザーを救え」
‘ =========================================================================
Public Sub ConnectToExternalDatabaseSample()

‘ 1. オブジェクト変数の宣言(メモリの適切な管理がプロへの第一歩)
Dim cnn As Object
Dim connectionString As String
Dim logFilePath As String

‘ エラーハンドラーの有効化
On Error GoTo ErrorHandler

‘ 2. ログファイルの保存先パスを指定(ここではAccessファイルと同じフォルダに「ErrorLog.txt」を作る)
logFilePath = CurrentProject.Path & “\DatabaseErrorLog.txt”

‘ 3. ADO接続文字列の構築(※環境に合わせて書き換えてください)
‘ 今回は例として、よくあるSQL Serverへの接続を想定しています
connectionString = “Provider=MSOLEDBSQL;” & _
“Server=myServerAddress;” & _
“Database=myDataBase;” & _
“Uid=myUsername;” & _
“Pwd=myPassword;”

‘ 4. Connectionオブジェクトの生成
Set cnn = CreateObject(“ADODB.Connection”)

‘ 接続タイムアウトの設定(秒単位。応答がない場合に無限に固まるのを防ぐプロの技)
cnn.ConnectionTimeout = 15

‘ 5. 接続の実行(ここでエラーが起きる可能性が高い)
Debug.Print “データベースへの接続を試行します…”
cnn.Open connectionString

‘ — 接続成功時の処理 —
MsgBox “データベースへの接続に成功しました!”, vbInformation, “成功”

‘ 接続を閉じる
cnn.Close

CleanUp:
‘ 6. オブジェクトの解放(メモリリークを絶対に防ぐ)
Set cnn = Nothing
Exit Sub

ErrorHandler:
‘ =========================================================================
‘ 7. エラーキャッチとFSOによるログファイル出力
‘ =========================================================================
Dim fso As Object
Dim ts As Object
Dim errDetail As String
Dim adoErr As Object

‘ 詳細なエラーメッセージを組み立てる
errDetail = “————————————————–[CRITICAL ERROR]” & vbCrLf
errDetail = errDetail & “発生時刻: ” & Now & vbCrLf
errDetail = errDetail & “エラー番号: ” & Err.Number & vbCrLf
errDetail = errDetail & “基本説明: ” & Err.Description & vbCrLf

‘ ADO固有の詳細エラー(複数のエラーがスタックされることがあるためループで回収)
On Error Resume Next ‘ ログ出力中の予期せぬエラーで無限ループするのを防ぐ
Set fso = CreateObject(“Scripting.FileSystemObject”)

If cnn Is Not Nothing Then
If cnn.Errors.Count > 0 Then
errDetail = errDetail & “— ADO Provider Errors —” & vbCrLf
For Each adoErr In cnn.Errors
errDetail = errDetail & ” [Native Error]: ” & adoErr.Number & vbCrLf
errDetail = errDetail & ” [Description]: ” & adoErr.Description & vbCrLf
errDetail = errDetail & ” [Source]: ” & adoErr.Source & vbCrLf
Next adoErr
End If
End If

‘ 8. FileSystemObject (FSO) を使ってテキストファイルに追記(Appendモード: 8)
‘ ※ファイルが存在しない場合は自動作成されます
Set ts = fso.OpenTextFile(logFilePath, 8, True)
ts.WriteLine errDetail
ts.Close

‘ オブジェクト解放
Set ts = Nothing
Set fso = Nothing

‘ 9. ユーザーへは優しく、しかし状況が伝わる通知を行う
MsgBox “データベースへの接続に失敗しました。” & vbCrLf & _
“管理者にお問い合わせください。” & vbCrLf & _
“ログ出力先: ” & logFilePath, vbCritical, “接続エラー”

Resume CleanUp
End Sub

—

Deeper Dive(深掘り解説):コードの要所を紐解く

このコードには、実務で生き抜くための「エンジニアの知恵」がふんだんに盛り込まれています。大切なポイントをいくつか解説しますね。

1. `CreateObject` による遅延バインディング(Late Binding)

コード内で `CreateObject(“ADODB.Connection”)` や `CreateObject(“Scripting.FileSystemObject”)` と書いています。
これは「参照設定(COMコンポーネントのチェック)」をあらかじめ行わなくても動く遅延バインディングという手法です。Accessのバージョン違い(32bit/64bitの混在や、Officeのバージョンの相違)による「参照設定の破損(コンパイルエラー)」を綺麗に回避できるため、配布するシステムではこの書き方が非常に好まれます。

2. ADOのエラーは `cnn.Errors` コレクションを見る

通常のVBAのエラー(`Err.Number`)は、最後におきた表面的なエラーしか教えてくれません。しかし、ADOの裏側では、データベースサーバーが発した複数の詳細なエラーが「Errorsコレクション」に蓄積されています。
コード内の `For Each adoErr In cnn.Errors` 部分がまさにそれです。「なぜ接続できないのか」の本当の原因(パスワード間違いなのか、ネットワーク不通なのか)は、大抵この中に眠っています。

3. `FileSystemObject (FSO)` での安全なログ追記

`fso.OpenTextFile(logFilePath, 8, True)` の `8` という数字は、「追記モード(ForAppending)」を意味します。最後の `True` は「ファイルが無ければ新規作成する」という指定です。
上書き(2番目の引数に `2` を指定)してしまうと、過去のエラー履歴が消えてしまうので、運用保守では「追記(8)」が絶対の鉄則です。

—

陥りやすい罠とアドバイス

初心者のうちは、次のようなミスでハマりがちです。

  • 「ログファイルのパスが書き込めない場所にある」

Cドライブの直下やWindowsのシステムフォルダを指定すると、権限不足(アクセス拒否)でログが書けずにプログラムがさらにクラッシュします。必ず `CurrentProject.Path`(Accessファイルと同じ場所)や、ユーザーのドキュメントフォルダ、専用の共有フォルダを指定しましょう。

  • エラーハンドラー内でエラーが起きる

エラー処理の中にバグがあると、無限ループやVBAの強制終了を招きます。エラーハンドラーの先頭に必ず `On Error Resume Next` を置き、ログ書き込み処理が安全に行われるように身構えておくのがプロの作法です。

—

まとめ:ここをクリアすれば、Access VBAの基本はバッチリですよ!

いかがでしたでしょうか?
「画面にエラーメッセージを出して終わり」のコードから、「確実にログを残し、ユーザーには優しく、開発者には詳細を伝える」コードへ。このステップを踏むだけで、あなたが作るAccessアプリの信頼性はプロのレベルへと跳ね上がります。

運用保守の現場で最も恐ろしいのは、「エラーが起きたことすら分からない」という状態です。FSOとADOのエラーハンドリングを味方につければ、どんなトラブルが起きても冷静に原因を特定し、迅速に対応できるようになります。

ここをクリアしたあなたなら、もう初級者ではありません。自信を持って、次の開発に臨んでくださいね!あなたのエンジニアライフを応援しています。

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