【ExcelVBA・マクロ】ADODBオブジェクト完全ガイド【SQL Server・Access接続からトランザクション処理まで実例25パターンで徹底解説】

ADODBオブジェクト完全ガイド ExcelVBA

この記事では以下の悩みを実例コード25パターンで解決します

  • データベースへの接続方法が分からない
  • SQL文でのデータ取得・更新・削除方法を知りたい
  • Recordsetオブジェクトの使い方がわからない
  • トランザクション処理を実装したい
  • SQLインジェクション対策をしたい
  • 参照設定 vs CreateObject の使い分けを知りたい

ADODBとは?

ADODB(ActiveX Data Objects Database)は、VBAからデータベースに接続してデータを操作するためのMicrosoft提供のライブラリです。

主要オブジェクト3つ

オブジェクト役割主な用途
ADODB.Connectionデータベース接続DB接続・切断・トランザクション管理
ADODB.Recordsetデータ取得・操作SELECT結果の取得・レコード追加/更新/削除
ADODB.CommandSQL実行パラメータ付きSQL実行・ストアドプロシージャ呼び出し

対応データベース

  • SQL Server
  • Microsoft Access
  • MySQL
  • Oracle
  • PostgreSQL
  • Excel・CSV(テキストファイル)

参照設定 vs CreateObjectの比較

比較表

項目参照設定(早期バインディング)CreateObject(遅延バインディング)
宣言Dim cn As ADODB.ConnectionDim cn As Object
生成Set cn = New ADODB.ConnectionSet cn = CreateObject("ADODB.Connection")
インテリセンス✔ あり✗ なし
処理速度速い少し遅い
配布参照設定が必要不要
環境依存高い低い
推奨度開発時配布用・複数環境

CreateObjectについて詳しく知りたい方はこちらをご覧ください。

【ExcelVBA・マクロ】CreateObject完全ガイド【外部ライブラリ連携の基本から実務活用まで徹底解説】
この記事で解決できる悩み ✅ CreateObjectの使い方が分からない ✅ 参照設定との違いが分からない ✅ FileSystemObjectやDictionaryの使い方が知りたい ✅ エラー429「オブジェクトを作成できません」が出...

参照設定の追加方法

  1. VBE(Visual Basic Editor)を開く
  2. ツール参照設定
  3. Microsoft ActiveX Data Objects 6.1 Library にチェック ✔
  4. OK をクリック

推奨

  • 開発時: 参照設定(インテリセンスが使える)
  • 配布時: CreateObject(環境に依存しない)

ADODB.Connectionオブジェクト完全解説

Connectionオブジェクトは データベース接続 を管理します。

主なプロパティ・メソッド

名前種類説明
ConnectionStringプロパティ接続文字列を設定
Stateプロパティ接続状態(0=閉、1=開)
Openメソッド接続を開く
Closeメソッド接続を閉じる
ExecuteメソッドSQL文を実行(INSERT/UPDATE/DELETE)
BeginTransメソッドトランザクション開始
CommitTransメソッドトランザクション確定
RollbackTransメソッドトランザクション取り消し

基本コード例

Sub ConnectDatabase()
    Dim cn As Object
    Set cn = CreateObject("ADODB.Connection")
    
    On Error GoTo ErrHandler
    
    ' 接続文字列を設定
    cn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=SalesDB;Integrated Security=SSPI;"
    
    ' 接続を開く
    cn.Open
    
    ' 接続状態を確認
    If cn.State = 1 Then
        Debug.Print "接続成功!"
    End If
    
    ' 接続を閉じる
    cn.Close
    Set cn = Nothing
    Exit Sub
    
ErrHandler:
    MsgBox "接続エラー: " & Err.Description
    If Not cn Is Nothing Then
        If cn.State = 1 Then cn.Close
        Set cn = Nothing
    End If
End Sub

接続文字列一覧表(SQL Server・Access・MySQL)

SQL Server

認証方法接続文字列
Windows認証Provider=SQLOLEDB;Data Source=サーバー名;Initial Catalog=DB名;Integrated Security=SSPI;
SQL Server認証Provider=SQLOLEDB;Data Source=サーバー名;Initial Catalog=DB名;User ID=ユーザー名;Password=パスワード;

Microsoft Access

Access バージョン接続文字列
Access 2007以降(.accdb)Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Database\sales.accdb;
Access 2003以前(.mdb)Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Database\sales.mdb;
パスワード保護ありProvider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Database\sales.accdb;Jet OLEDB:Database Password=パスワード;

MySQL

Driver={MySQL ODBC 8.0 Unicode Driver};Server=localhost;Database=salesdb;User=root;Password=password;

Excel ファイル

Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Data\sales.xlsx;Extended Properties="Excel 12.0 Xml;HDR=YES;IMEX=1";

HDR=YES: 1行目を列名として扱う
IMEX=1: 型混在列を文字列として読み込む


ADODB.Recordsetオブジェクト完全解説

Recordsetオブジェクトは データの取得・操作 を行います。

主なプロパティ・メソッド

名前種類説明
EOFプロパティ最終レコードを超えたか
BOFプロパティ先頭レコードより前か
RecordCountプロパティレコード件数
Fieldsコレクションフィールド(列)の集合
OpenメソッドRecordsetを開く
CloseメソッドRecordsetを閉じる
MoveNextメソッド次のレコードへ移動
MovePreviousメソッド前のレコードへ移動
MoveFirstメソッド先頭レコードへ移動
MoveLastメソッド最終レコードへ移動
AddNewメソッド新規レコード追加
Updateメソッド変更を確定
Deleteメソッドレコード削除

SELECT文でデータ取得

Sub SelectData()
    Dim cn As Object, rs As Object
    Set cn = CreateObject("ADODB.Connection")
    Set rs = CreateObject("ADODB.Recordset")
    
    On Error GoTo ErrHandler
    
    ' 接続
    cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Database\sales.accdb;"
    cn.Open
    
    ' SQL実行
    rs.Open "SELECT * FROM 顧客マスタ WHERE 都道府県 = '東京都'", cn
    
    ' データ取得
    Do Until rs.EOF
        Debug.Print rs.Fields("顧客ID").Value & " - " & rs.Fields("顧客名").Value
        rs.MoveNext
    Loop
    
    ' クリーンアップ
    rs.Close
    cn.Close
    Set rs = Nothing
    Set cn = Nothing
    Exit Sub
    
ErrHandler:
    MsgBox "エラー: " & Err.Description
    If Not rs Is Nothing Then If rs.State = 1 Then rs.Close
    If Not cn Is Nothing Then If cn.State = 1 Then cn.Close
End Sub

ExcelシートへRecordsetを出力

Sub ExportToExcel()
    Dim cn As Object, rs As Object
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("Sheet1")
    Set cn = CreateObject("ADODB.Connection")
    Set rs = CreateObject("ADODB.Recordset")
    
    On Error GoTo ErrHandler
    
    cn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=SalesDB;Integrated Security=SSPI;"
    cn.Open
    
    rs.Open "SELECT * FROM 売上データ WHERE 売上日 >= '2026-01-01'", cn
    
    ' 列名を出力
    Dim i As Integer
    For i = 0 To rs.Fields.Count - 1
        ws.Cells(1, i + 1).Value = rs.Fields(i).Name
    Next i
    
    ' データを出力(CopyFromRecordsetが高速)
    ws.Range("A2").CopyFromRecordset rs
    
    rs.Close
    cn.Close
    Set rs = Nothing
    Set cn = Nothing
    MsgBox "データ出力完了!"
    Exit Sub
    
ErrHandler:
    MsgBox "エラー: " & Err.Description
End Sub

ADODB.Commandオブジェクトとパラメータクエリ

Commandオブジェクトは パラメータ付きSQL実行 とSQLインジェクション対策に使用します。

基本構文

Sub CommandExample()
    Dim cn As Object, cmd As Object
    Set cn = CreateObject("ADODB.Connection")
    Set cmd = CreateObject("ADODB.Command")
    
    On Error GoTo ErrHandler
    
    cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Database\sales.accdb;"
    cn.Open
    
    ' Commandオブジェクト設定
    Set cmd.ActiveConnection = cn
    cmd.CommandText = "INSERT INTO 売上データ (商品ID, 数量, 売上日) VALUES (?, ?, ?)"
    cmd.CommandType = 1  ' adCmdText
    
    ' パラメータ追加
    cmd.Parameters.Append cmd.CreateParameter("商品ID", 3, 1, , 101)  ' adInteger
    cmd.Parameters.Append cmd.CreateParameter("数量", 3, 1, , 5)
    cmd.Parameters.Append cmd.CreateParameter("売上日", 7, 1, , Date)  ' adDate
    
    ' 実行
    cmd.Execute
    
    cn.Close
    Set cmd = Nothing
    Set cn = Nothing
    MsgBox "レコード追加完了!"
    Exit Sub
    
ErrHandler:
    MsgBox "エラー: " & Err.Description
End Sub

パラメータ型一覧

データ型数値定数名
文字列200adVarChar
整数3adInteger
長整数20adBigInt
日付7adDate
通貨6adCurrency
ブール11adBoolean
倍精度浮動小数点5adDouble

SQL操作実例(SELECT・INSERT・UPDATE・DELETE)

INSERT文(新規登録)

Sub InsertRecord()
    Dim cn As Object
    Set cn = CreateObject("ADODB.Connection")
    
    On Error GoTo ErrHandler
    
    cn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=SalesDB;Integrated Security=SSPI;"
    cn.Open
    
    Dim sql As String
    sql = "INSERT INTO 顧客マスタ (顧客名, 都道府県, 電話番号) " & _
          "VALUES ('株式会社サンプル', '東京都', '03-1234-5678')"
    
    cn.Execute sql
    
    cn.Close
    Set cn = Nothing
    MsgBox "登録完了!"
    Exit Sub
    
ErrHandler:
    MsgBox "エラー: " & Err.Description
End Sub

UPDATE文(更新)

Sub UpdateRecord()
    Dim cn As Object
    Set cn = CreateObject("ADODB.Connection")
    
    On Error GoTo ErrHandler
    
    cn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=SalesDB;Integrated Security=SSPI;"
    cn.Open
    
    Dim sql As String
    sql = "UPDATE 顧客マスタ SET 電話番号 = '03-9999-8888' WHERE 顧客ID = 1001"
    
    cn.Execute sql
    
    cn.Close
    Set cn = Nothing
    MsgBox "更新完了!"
    Exit Sub
    
ErrHandler:
    MsgBox "エラー: " & Err.Description
End Sub

DELETE文(削除)

Sub DeleteRecord()
    Dim cn As Object
    Set cn = CreateObject("ADODB.Connection")
    
    On Error GoTo ErrHandler
    
    cn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=SalesDB;Integrated Security=SSPI;"
    cn.Open
    
    Dim sql As String
    sql = "DELETE FROM 売上データ WHERE 売上日 < '2025-01-01'"
    
    ' 確認ダイアログ
    If MsgBox("古いデータを削除しますか?", vbYesNo) = vbYes Then
        cn.Execute sql
        MsgBox "削除完了!"
    End If
    
    cn.Close
    Set cn = Nothing
    Exit Sub
    
ErrHandler:
    MsgBox "エラー: " & Err.Description
End Sub

Recordsetのレコード操作(AddNew・Update・Delete)

AddNew(レコード追加)

Sub AddNewRecord()
    Dim cn As Object, rs As Object
    Set cn = CreateObject("ADODB.Connection")
    Set rs = CreateObject("ADODB.Recordset")
    
    On Error GoTo ErrHandler
    
    cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Database\sales.accdb;"
    cn.Open
    
    ' Recordsetを開く(更新可能モード)
    rs.Open "SELECT * FROM 顧客マスタ", cn, 1, 3  ' adOpenKeyset, adLockOptimistic
    
    ' 新規レコード追加
    rs.AddNew
    rs.Fields("顧客名").Value = "テスト株式会社"
    rs.Fields("都道府県").Value = "大阪府"
    rs.Fields("電話番号").Value = "06-1234-5678"
    rs.Update  ' 確定
    
    rs.Close
    cn.Close
    Set rs = Nothing
    Set cn = Nothing
    MsgBox "追加完了!"
    Exit Sub
    
ErrHandler:
    MsgBox "エラー: " & Err.Description
End Sub

Update(レコード更新)

Sub UpdateRecordset()
    Dim cn As Object, rs As Object
    Set cn = CreateObject("ADODB.Connection")
    Set rs = CreateObject("ADODB.Recordset")
    
    On Error GoTo ErrHandler
    
    cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Database\sales.accdb;"
    cn.Open
    
    rs.Open "SELECT * FROM 顧客マスタ WHERE 顧客ID = 1001", cn, 1, 3
    
    If Not rs.EOF Then
        rs.Fields("電話番号").Value = "03-5555-6666"
        rs.Update
        MsgBox "更新完了!"
    Else
        MsgBox "対象レコードが見つかりません"
    End If
    
    rs.Close
    cn.Close
    Set rs = Nothing
    Set cn = Nothing
    Exit Sub
    
ErrHandler:
    MsgBox "エラー: " & Err.Description
End Sub

Delete(レコード削除)

Sub DeleteRecordset()
    Dim cn As Object, rs As Object
    Set cn = CreateObject("ADODB.Connection")
    Set rs = CreateObject("ADODB.Recordset")
    
    On Error GoTo ErrHandler
    
    cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Database\sales.accdb;"
    cn.Open
    
    rs.Open "SELECT * FROM 顧客マスタ WHERE 顧客ID = 9999", cn, 1, 3
    
    If Not rs.EOF Then
        rs.Delete
        MsgBox "削除完了!"
    Else
        MsgBox "対象レコードが見つかりません"
    End If
    
    rs.Close
    cn.Close
    Set rs = Nothing
    Set cn = Nothing
    Exit Sub
    
ErrHandler:
    MsgBox "エラー: " & Err.Description
End Sub

トランザクション処理(BeginTrans・CommitTrans・RollbackTrans)

トランザクション = 複数のSQL処理を 一つのまとまった処理 として扱う仕組み

トランザクション3つのメソッド

メソッド役割
BeginTransトランザクション開始
CommitTransすべての変更を確定
RollbackTransすべての変更を取り消し

トランザクション処理テンプレート

Sub TransactionExample()
    Dim cn As Object
    Set cn = CreateObject("ADODB.Connection")
    
    On Error GoTo ErrHandler
    
    cn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=SalesDB;Integrated Security=SSPI;"
    cn.Open
    
    ' トランザクション開始
    cn.BeginTrans
    
    ' 複数のSQL実行
    cn.Execute "INSERT INTO 売上データ (商品ID, 数量, 売上日) VALUES (101, 5, '2026-02-17')"
    cn.Execute "UPDATE 在庫マスタ SET 在庫数 = 在庫数 - 5 WHERE 商品ID = 101"
    
    ' すべて成功したら確定
    cn.CommitTrans
    
    cn.Close
    Set cn = Nothing
    MsgBox "トランザクション完了!"
    Exit Sub
    
ErrHandler:
    ' エラー時は全て取り消し
    If Not cn Is Nothing Then
        If cn.State = 1 Then cn.RollbackTrans
        cn.Close
    End If
    Set cn = Nothing
    MsgBox "エラー: " & Err.Description & vbCrLf & "全ての変更を取り消しました。"
End Sub

在庫引当処理の実務例

Sub StockAllocation()
    Dim cn As Object
    Set cn = CreateObject("ADODB.Connection")
    
    On Error GoTo ErrHandler
    
    cn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=SalesDB;Integrated Security=SSPI;"
    cn.Open
    
    cn.BeginTrans
    
    ' 在庫確認
    Dim rs As Object
    Set rs = CreateObject("ADODB.Recordset")
    rs.Open "SELECT 在庫数 FROM 在庫マスタ WHERE 商品ID = 101", cn
    
    If rs.EOF Or rs.Fields("在庫数").Value < 10 Then
        rs.Close
        Set rs = Nothing
        Err.Raise vbObjectError + 1, , "在庫不足"
    End If
    rs.Close
    Set rs = Nothing
    
    ' 売上登録
    cn.Execute "INSERT INTO 売上データ (商品ID, 数量, 売上日) VALUES (101, 10, '2026-02-17')"
    
    ' 在庫減算
    cn.Execute "UPDATE 在庫マスタ SET 在庫数 = 在庫数 - 10 WHERE 商品ID = 101"
    
    cn.CommitTrans
    cn.Close
    Set cn = Nothing
    MsgBox "在庫引当完了!"
    Exit Sub
    
ErrHandler:
    If Not cn Is Nothing Then
        If cn.State = 1 Then cn.RollbackTrans
        cn.Close
    End If
    Set cn = Nothing
    MsgBox "エラー: " & Err.Description
End Sub

SQLインジェクション対策

❌ 危険なコード例(文字列連結)

' ユーザー入力値をそのまま埋め込む(絶対NG!)
Dim userName As String
userName = InputBox("ユーザー名を入力してください")

Dim sql As String
sql = "SELECT * FROM ユーザーマスタ WHERE ユーザー名 = '" & userName & "'"
' もし userName に「' OR '1'='1」と入力されると...
' → SELECT * FROM ユーザーマスタ WHERE ユーザー名 = '' OR '1'='1'
' → 全レコード取得される(セキュリティホール!)

✅ 安全なコード例(パラメータクエリ)

Sub SafeQuery()
    Dim cn As Object, cmd As Object, rs As Object
    Set cn = CreateObject("ADODB.Connection")
    Set cmd = CreateObject("ADODB.Command")
    
    On Error GoTo ErrHandler
    
    cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Database\sales.accdb;"
    cn.Open
    
    ' ユーザー入力
    Dim userName As String
    userName = InputBox("ユーザー名を入力してください")
    
    ' パラメータクエリ
    Set cmd.ActiveConnection = cn
    cmd.CommandText = "SELECT * FROM ユーザーマスタ WHERE ユーザー名 = ?"
    cmd.CommandType = 1
    
    ' パラメータ追加(自動的にエスケープされる)
    cmd.Parameters.Append cmd.CreateParameter("userName", 200, 1, 50, userName)
    
    Set rs = cmd.Execute
    
    If Not rs.EOF Then
        Debug.Print rs.Fields("ユーザー名").Value
    Else
        Debug.Print "該当なし"
    End If
    
    rs.Close
    cn.Close
    Set rs = Nothing
    Set cmd = Nothing
    Set cn = Nothing
    Exit Sub
    
ErrHandler:
    MsgBox "エラー: " & Err.Description
End Sub

SQLインジェクション対策まとめ

対策説明推奨度
パラメータクエリCommandオブジェクトでパラメータ化★★★ 最優先
エスケープ処理シングルクォートを2重化 Replace(input, "'", "''")★★☆ 補助
入力値検証数値・日付・文字種をチェック★★★ 必須
文字列連結禁止SQL文へのユーザー入力直接埋め込みを禁止★★★ 絶対

実務テンプレート5選

① Excel → SQL Server 一括登録

Sub BulkInsert()
    Dim cn As Object
    Set cn = CreateObject("ADODB.Connection")
    
    On Error GoTo ErrHandler
    
    cn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=SalesDB;Integrated Security=SSPI;"
    cn.Open
    
    cn.BeginTrans
    
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("データ")
    
    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
    
    Dim i As Long
    For i = 2 To lastRow  ' 2行目から(1行目は列名)
        Dim sql As String
        sql = "INSERT INTO 売上データ (商品ID, 数量, 売上日) VALUES (" & _
              ws.Cells(i, 1).Value & ", " & _
              ws.Cells(i, 2).Value & ", '" & _
              Format(ws.Cells(i, 3).Value, "yyyy-mm-dd") & "')"
        cn.Execute sql
    Next i
    
    cn.CommitTrans
    cn.Close
    Set cn = Nothing
    MsgBox lastRow - 1 & " 件登録完了!"
    Exit Sub
    
ErrHandler:
    If Not cn Is Nothing Then
        If cn.State = 1 Then cn.RollbackTrans
        cn.Close
    End If
    Set cn = Nothing
    MsgBox "エラー: " & Err.Description
End Sub

② CSV エクスポート

Sub ExportToCSV()
    Dim cn As Object, rs As Object
    Dim fso As Object, txt As Object
    Set cn = CreateObject("ADODB.Connection")
    Set rs = CreateObject("ADODB.Recordset")
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    On Error GoTo ErrHandler
    
    cn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=SalesDB;Integrated Security=SSPI;"
    cn.Open
    
    rs.Open "SELECT * FROM 売上データ WHERE 売上日 >= '2026-01-01'", cn
    
    ' CSV作成
    Set txt = fso.CreateTextFile("C:\Export\売上データ_" & Format(Date, "yyyymmdd") & ".csv", True)
    
    ' ヘッダー行
    Dim header As String
    Dim i As Integer
    For i = 0 To rs.Fields.Count - 1
        header = header & rs.Fields(i).Name & ","
    Next i
    txt.WriteLine Left(header, Len(header) - 1)
    
    ' データ行
    Do Until rs.EOF
        Dim row As String
        For i = 0 To rs.Fields.Count - 1
            row = row & rs.Fields(i).Value & ","
        Next i
        txt.WriteLine Left(row, Len(row) - 1)
        row = ""
        rs.MoveNext
    Loop
    
    txt.Close
    rs.Close
    cn.Close
    Set txt = Nothing
    Set fso = Nothing
    Set rs = Nothing
    Set cn = Nothing
    MsgBox "CSV出力完了!"
    Exit Sub
    
ErrHandler:
    MsgBox "エラー: " & Err.Description
End Sub

③ 複数テーブルJOIN取得

Sub JoinQuery()
    Dim cn As Object, rs As Object
    Set cn = CreateObject("ADODB.Connection")
    Set rs = CreateObject("ADODB.Recordset")
    
    On Error GoTo ErrHandler
    
    cn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=SalesDB;Integrated Security=SSPI;"
    cn.Open
    
    Dim sql As String
    sql = "SELECT s.売上ID, c.顧客名, p.商品名, s.数量, s.売上日 " & _
          "FROM 売上データ s " & _
          "INNER JOIN 顧客マスタ c ON s.顧客ID = c.顧客ID " & _
          "INNER JOIN 商品マスタ p ON s.商品ID = p.商品ID " & _
          "WHERE s.売上日 >= '2026-01-01'"
    
    rs.Open sql, cn
    
    ' Excelシートへ出力
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("売上一覧")
    
    ' 列名
    Dim i As Integer
    For i = 0 To rs.Fields.Count - 1
        ws.Cells(1, i + 1).Value = rs.Fields(i).Name
    Next i
    
    ' データ
    ws.Range("A2").CopyFromRecordset rs
    
    rs.Close
    cn.Close
    Set rs = Nothing
    Set cn = Nothing
    MsgBox "データ取得完了!"
    Exit Sub
    
ErrHandler:
    MsgBox "エラー: " & Err.Description
End Sub

④ ストアドプロシージャ実行

Sub CallStoredProcedure()
    Dim cn As Object, cmd As Object
    Set cn = CreateObject("ADODB.Connection")
    Set cmd = CreateObject("ADODB.Command")
    
    On Error GoTo ErrHandler
    
    cn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=SalesDB;Integrated Security=SSPI;"
    cn.Open
    
    Set cmd.ActiveConnection = cn
    cmd.CommandText = "usp_GetMonthlySales"  ' ストアドプロシージャ名
    cmd.CommandType = 4  ' adCmdStoredProc
    
    ' パラメータ追加
    cmd.Parameters.Append cmd.CreateParameter("@Year", 3, 1, , 2026)
    cmd.Parameters.Append cmd.CreateParameter("@Month", 3, 1, , 2)
    
    Dim rs As Object
    Set rs = cmd.Execute
    
    ' 結果取得
    Do Until rs.EOF
        Debug.Print rs.Fields("売上合計").Value
        rs.MoveNext
    Loop
    
    rs.Close
    cn.Close
    Set rs = Nothing
    Set cmd = Nothing
    Set cn = Nothing
    Exit Sub
    
ErrHandler:
    MsgBox "エラー: " & Err.Description
End Sub

⑤ リトライ機能付き接続

Function ConnectWithRetry(connectionString As String, maxRetry As Integer) As Object
    Dim cn As Object
    Set cn = CreateObject("ADODB.Connection")
    
    Dim retry As Integer
    retry = 0
    
    Do
        On Error Resume Next
        cn.Open connectionString
        If Err.Number = 0 Then
            On Error GoTo 0
            Set ConnectWithRetry = cn
            Exit Function
        End If
        
        retry = retry + 1
        Debug.Print "接続失敗(試行 " & retry & "/" & maxRetry & "): " & Err.Description
        Err.Clear
        Application.Wait Now + TimeValue("00:00:03")  ' 3秒待機
    Loop While retry < maxRetry
    
    On Error GoTo 0
    MsgBox "接続失敗: " & maxRetry & " 回試行しましたが接続できませんでした。"
    Set ConnectWithRetry = Nothing
End Function

' 使用例
Sub UseRetryConnection()
    Dim cn As Object
    Set cn = ConnectWithRetry("Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=SalesDB;Integrated Security=SSPI;", 3)
    
    If Not cn Is Nothing Then
        Debug.Print "接続成功!"
        cn.Close
        Set cn = Nothing
    End If
End Sub

よくある質問(FAQ 7問)

Q1. 参照設定とCreateObject、どちらを使うべきですか?

A. 用途によって使い分けます。

  • 開発時: 参照設定(インテリセンスが使える、高速)
  • 配布時: CreateObject(環境依存しない、配布が楽)

多くの場合、開発中は参照設定を有効にして開発し、配布前に CreateObject へ書き換えます。


Q2. Recordsetの RecordCount が -1 になります

A. カーソルタイプを変更してください。

' デフォルト(adOpenForwardOnly)では RecordCount が取得できない
rs.Open sql, cn

' adOpenKeyset または adOpenStatic を使用
rs.Open sql, cn, 1  ' adOpenKeyset
' または
rs.Open sql, cn, 3  ' adOpenStatic

カーソルタイプ一覧

定数値定数名RecordCountMovePrevious
0adOpenForwardOnly
1adOpenKeyset
2adOpenDynamic
3adOpenStatic

Q3. Recordsetを更新できません

A. ロックタイプを変更してください。

' 読み取り専用(デフォルト)
rs.Open sql, cn, 1, 1  ' adLockReadOnly

' 更新可能にする
rs.Open sql, cn, 1, 3  ' adLockOptimistic

ロックタイプ一覧

定数値定数名更新説明
1adLockReadOnly読み取り専用
2adLockPessimistic悲観的ロック(編集時にロック)
3adLockOptimistic楽観的ロック(更新時にロック)
4adLockBatchOptimisticバッチ更新

Q4. 「オブジェクトが閉じている場合は、操作は許可されません」エラー

A. Recordset/Connectionが閉じています。

' 確認してから操作
If cn.State = 1 Then  ' adStateOpen
    ' 接続中
End If

If rs.State = 1 Then
    ' Recordset開いている
End If

Q5. SQL Server の日本語が文字化けします

A. 接続文字列に文字コード指定を追加してください。

cn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=SalesDB;Integrated Security=SSPI;Auto Translate=True;"

Q6. 大量データを高速で取得したい

A. CopyFromRecordset メソッドを使用してください。

' ❌ 遅い方法(1行ずつループ)
Do Until rs.EOF
    ws.Cells(i, 1).Value = rs.Fields(0).Value
    i = i + 1
    rs.MoveNext
Loop

' ✅ 高速方法(一括コピー)
ws.Range("A2").CopyFromRecordset rs

大量データ(数万件以上)では 10〜100倍 の速度差が出ます。


Q7. エラー「プロバイダーが見つかりません」

A. OLEDBプロバイダーがインストールされていません。

対策:

  • SQL Server: SQL Server Native Client または ODBC Driver をインストール
  • Access 2007以降: Microsoft Access Database Engine 2016 をインストール
  • 32bit/64bit: Officeのビットと一致するプロバイダーをインストール

確認方法: コントロールパネル → 管理ツール → ODBC データソース


まとめと次のステップ

本記事のまとめ

✅ ADODBの3大オブジェクト(Connection・Recordset・Command)を習得
✅ SQL Server・Access・MySQLへの接続方法を習得
✅ SELECT・INSERT・UPDATE・DELETEの実装方法を習得
✅ トランザクション処理で複数SQL処理を安全に実行
✅ SQLインジェクション対策でセキュリティ強化
✅ 実務テンプレート5選で即戦力化

スポンサーリンク
スポンサーリンク
ExcelVBA
いがぴをフォローする

コメント

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