【入門編】ADOの接続エラーを詳細に解析する:Errorsコレクションを活用したデバッグ術 – Access VBA解析バイブル

スポンサーリンク
スポンサーリンク

「実行時エラー ‘3704’」の正体を見破れ!ADOのErrorsコレクションでSQL Serverの真実を掴むデバッグ術

こんにちは。現場の設計から自動化の極致まで、コードの裏側に潜む「真実」を追い求めているエンジニアです。

Access VBAで、SQL Serverなどの外部データベースに接続する処理を書いていて、こんな経験はありませんか?

「実行時エラー ‘3704’: オブジェクトが閉じているため、操作は許可されません」
「実行時エラー ‘-2147467259’: 接続に失敗しました」

……正直に言いましょう。これらのメッセージだけでは、解決の糸口すら見えないことがほとんどです。

なぜなら、それらはADO(ActiveX Data Objects)という「仲介役」が、エラーを要約して伝えてきている「表面的なメッセージ」に過ぎないからです。本当の原因は、その奥底、SQL Serverの心臓部が叫んでいるエラーメッセージの中に隠されています。

今日は、マクロの記録から一歩踏み出し、「プロのデバッグ」へと昇華するための極意――ADOの `Errors` コレクションを活用した詳細解析術を伝授します。ここをクリアすれば、Access VBAのデバッグ能力は劇的に向上しますよ。

なぜ、標準のエラーメッセージでは足りないのか?

まず、アーキテクチャ(構造)のイメージを掴みましょう。

あなたが書いたVBAコードがSQL Serverに命令を出すとき、以下のようなリレーが行われています。

1. あなたのVBAコード(命令を出す)
2. ADO(仲介役)(命令をプロバイダに渡す)
3. OLE DB プロバイダ(通訳者)(命令をSQL Serverがわかる形式に変換する)
4. SQL Server(本体)(命令を実行し、エラーがあれば返す)

エラーが発生したとき、`Err.Description` が教えてくれるのは、一番最後の「仲介役」が要約した言葉です。

しかし、本当の原因は 4(SQL Server) が「主キーが重複しているよ!」とか「権限が足りないよ!」と叫んでいる内容です。この「叫び」の全容を、ADOは `Errors` コレクションという場所に、エラーの発生順にすべて蓄積してくれています。

私たちは、この隠されたリストを直接覗きに行く必要があるのです。

核心:Errorsコレクションの使いかた

ADOにおいて、エラー情報は `ADODB.Connection` オブジェクト、または `ADODB.Command` オブジェクトの `Errors` プロパティに格納されます。

重要なプロパティは以下の4つです。

プロパティ名 役割 現場での重要度
`.Number` ADOが割り当てたエラー番号 中(分類に使う)
`.Description` エラーの内容(説明文) 高(読みやすい)
`.SQLState` 標準化されたエラー状態コード 高(共通規格)
`.NativeError` SQL Server自身が返した生のエラー番号 極高(これが真実)

特に `NativeError` は、SQL Serverのドキュメントを引く際に必須となる「真実の番号」です。

実戦:詳細エラーを暴き出す最強のデバッグ関数

それでは、実際に現場でそのまま使える「エラー解析用コード」を書いてみましょう。
単にエラーを表示するだけでなく、エラーの階層をすべて掘り起こすロジックです。

Option Explicit

''' <summary>
''' SQL Serverへの接続テストと、エラー発生時の詳細解析を行うサンプル
''' </summary>
Public Sub TestConnectionAndAnalyzeError()
    Dim conn As ADODB.Connection
    Dim strConn As String
    
    ' --- 設定エリア:環境に合わせて書き換えてください ---
    ' 接続文字列の例(SQL Serverへの接続)
    strConn = "Provider=SQLNCLI11;Server=YOUR_SERVER_NAME;Database=YOUR_DB_NAME;Trusted_Connection=yes;"
    ' --------------------------------------------------

    Set conn = New ADODB.Connection

    On Error GoTo ErrorHandler

    ' 1. 接続を試みる
    Debug.Print "--- 接続開始 ---"
    conn.Open strConn
    Debug.Print "接続成功!"

    ' 2. 何か適当なSQLを実行してみる(エラーを誘発させる例として、存在しないテーブルを指定)
    Dim rs As ADODB.Recordset
    Set rs = conn.Execute("SELECT * FROM NonExistentTable") ' ←わざとエラーを出す

CleanUp:
    ' 後片付け
    If Not rs Is Nothing Then If rs.State = adStateOpen Then rs.Close
    If Not conn Is Nothing Then If conn.State = adStateOpen Then conn.Close
    Set rs = Nothing
    Set conn = Nothing
    Debug.Print "--- 処理終了 ---"
    Exit Sub

ErrorHandler:
    ' ここが重要!
    ' 標準のErrオブジェクトだけでなく、connオブジェクトのErrorsコレクションを解析する
    Call DetailedErrorLog(conn)
    
    ' 念のため標準のエラーも表示
    Debug.Print "【標準Errオブジェクト】"
    Debug.Print "番号: " & Err.Number & " / 内容: " & Err.Description
    
    Resume CleanUp
End Sub

''' <summary>
''' ADOのErrorsコレクションをループして、詳細なエラー情報を出力する
''' </summary>
''' <param name="conn">エラーを保持しているConnectionオブジェクト</param>
Private Sub DetailedErrorLog(ByRef conn As ADODB.Connection)
    Dim i As Integer
    
    Debug.Print "--- [詳細エラー解析レポート] ---"
    
    ' エラーが一つも溜まっていない場合は、Connection自体に問題がある
    If conn.Errors.Count = 0 Then
        Debug.Print "ADO Errorsコレクションは空です。ConnectionのOpen自体に失敗した可能性があります。"
        Exit Sub
    End If

    ' Errorsコレクションを最初から最後までスキャンする
    ' エラーは発生順に格納されている
    For i = 0 To conn.Errors.Count - 1
        With conn.Errors(i)
            Debug.Print "Error #" & (i + 1)
            Debug.Print "  [ADO Number]   : " & .Number
            Debug.Print "  [Description]  : " & .Description
            Debug.Print "  [SQLState]     : " & .SQLState
            Debug.Print "  [Native Error] : " & .NativeError ' ← これがSQL Serverの生の番号!
            Debug.Print "--------------------------------"
        End With
    Next i
End Sub

このコードのポイント

1. `conn.Errors.Count` の確認:
接続自体に失敗した場合、`conn.Open` の段階でエラーが発生するため、`conn` オブジェクトが正しく初期化されているか、あるいはエラーがどこに格納されているかを見極める必要があります。
2. ループ処理:
エラーは連鎖することがあります。「ネットワークが切れた」→「プロバイダがタイムアウトした」→「ADOが接続失敗を報告した」という具合です。`For i = 0 To conn.Errors.Count – 1` とすることで、その連鎖の一番最初(根本原因)を見つけることができます。
3. `NativeError` の出力:
これさえあれば、Googleで「SQL Server Native Error 2627」のように検索するだけで、一瞬で解決策に辿り着けます。

まとめ:エラーを「恐れる」のではなく「観察する」

プログラミング初学者のうちは、エラーが出ると「あ、失敗した。どこが悪いんだろう……」と、どこか自分を責めるような気持ちになってしまうかもしれません。

でも、ベテランエンジニアは違います。
私たちはエラーが出たとき、「お、ついに真実(Native Error)が姿を現したか」と、むしろ歓迎します。エラーは、プログラムがあなたに送ってくれた「どこを直すべきか」という精密な診断書なのですから。

今回紹介した `Errors` コレクションの解析術を使えば、今まで「なんとなく」で解決していたデバッグが、「確信」を持った作業に変わります。

「エラーメッセージの表面だけを見て、解決を諦めないこと」

これが、Access VBAをマスターし、真の自動化エンジニアへと成長するための第一歩です。応援していますよ。ここをクリアすれば、Access VBAの基本はバッチリですよ!

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