ExcelのVBAだけでMySQLに接続・取得・更新する手順
前提と環境の確認(32/64bit・権限・ドライバ前提)
VBAからMySQLへつなぐ前に、つまずきを減らすための前提をそろえます。ここでの確認ができていると、後のトラブル対応が速くなります。
- OfficeとWindowsのbit数を確認します。Excelのアカウント情報や「ファイル」→「アカウント」→「バージョン情報」で見られます。32bitのOfficeなら32bitのドライバ、64bitなら64bitのドライバが必要です。
- 用語をそろえます。ODBCはデータベース接続の共通規格、ADO(ADODB)はVBAからデータベースを操作するためのライブラリ、DSNは接続設定の名前です。本稿は「DSNを作らず、接続文字列だけでつなぐ」前提です。
- MySQL ODBC Driver(MySQL Connector/ODBC)がPCに入っているか確認します。社内PCでは既に導入済みのことが多いです。入っていない場合は管理者に依頼してください。
- 接続先の基本情報を整理します。サーバー名(またはIP)、ポート(初期値は3306)、データベース名、ユーザー名、パスワードです。これらは接続文字列で使います。
- DBユーザー権限を確認します。読み取りだけならSELECT権限、更新が必要ならINSERT/UPDATE/DELETE権限も必要です。最小権限が安全です。
この段階で、Recordsetのカーソルで迷ったら比較表を参照する予定です(本記事内:2. ADODB.Recordsetの使い方)。認証エラーが出る場合は、後半のエラー別チェックリストへ進んでください(本記事内:接続できない場合)。
FAQ:Officeが32bit/64bitだと接続で何が変わる?
bit数が違うと使うODBCドライバも違います。Excelが32bitなら32bitドライバ、64bitなら64bitドライバを使います。bit数が合わないと、ドライバが見つからないエラーが出ます。
基本的な接続方法(DSNなし/最短サンプル)
最短でつながる形をまず示します。DSNを作らず、接続文字列に必要情報を並べます。VBAではADODB.Connectionを使います。
最短の接続〜切断コード
“`vba
‘ 参照設定は不要(遅延バインディング)。
Sub MySqlConnectMinimal()
Dim cn As Object ‘ ADODB.Connection
Set cn = CreateObject(“ADODB.Connection”)
Dim connStr As String
connStr = “Driver={MySQL ODBC 8.0 ANSI Driver};” & _
“Server=your-host.example.com;” & _
“Database=your_db;” & _
“Uid=your_user;Pwd=your_password;” & _
“Port=3306;Option=3;”
On Error GoTo EH
cn.Open connStr
‘ ここで処理(SELECTや更新)を行う
Done:
On Error Resume Next
If Not cn Is Nothing Then If cn.State <> 0 Then cn.Close
Set cn = Nothing
Exit Sub
EH:
MsgBox “接続失敗: ” & Err.Number & ” ” & Err.Description
Resume Done
End Sub
“`
- 置き換える場所は、Server/Database/Uid/Pwd/Port です。Option=3 は一般的な互換設定です。
- タイムアウトは
cn.ConnectionTimeoutとcn.CommandTimeoutで調整します。最初は既定値のままで問題ありません。
エラー処理の最小形
On Error GoToで一か所に集約します。- 失敗時は
Err.NumberとErr.Descriptionをメッセージやログに残します。 - 最後に
Closeとオブジェクト破棄を忘れないことが安定運用につながります。
FAQ:接続文字列はどの部分を自分用に変えればよい?
Server、Database、Uid、Pwd、Portを自分の環境に合わせて変更します。社内DNSがない場合はServerにIPアドレスを書く方法もあります。
1. ADODB.Connectionの使い方(接続・切断・トランザクション)
ここではConnectionオブジェクトの基本を整理します。安定運用の観点から、タイムアウト、トランザクション、後始末に触れます。
Openとタイムアウト
“`vba
Dim cn As Object ‘ ADODB.Connection
Set cn = CreateObject(“ADODB.Connection”)
cn.ConnectionTimeout = 15 ‘ 接続確立の待ち時間(秒)
cn.CommandTimeout = 30 ‘ クエリ実行の待ち時間(秒)
cn.Open connStr
“`
ConnectionTimeoutはサーバーに接続するまでの待機。ネットワーク不調時の待ちすぎを防ぎます。CommandTimeoutはSQL実行の待機。重いクエリがある場合は適切に延ばします。
トランザクションの基本
更新をまとめて安全に行う場合に使います。
“`vba
cn.BeginTrans
On Error GoTo TX_EH
cn.Execute “UPDATE items SET price = price * 1.05 WHERE category=’A'”
cn.Execute “INSERT INTO logs(action, at) VALUES(‘bulk_update’, NOW())”
cn.CommitTrans
GoTo TX_DONE
TX_EH:
cn.RollbackTrans
MsgBox “ロールバックしました: ” & Err.Description
TX_DONE:
“`
- まとまった更新で部分的な反映を避けたいときに有効です。
- 例外が出たら必ず
RollbackTransで元に戻します。
明示的なCloseと破棄
- 処理が終わったら
cn.Closeを呼びます。接続を放置すると、サーバーの接続数上限に影響します。 - 使い終わったオブジェクトは
Set cn = Nothingとして解放します。
ログの取り方
- 失敗時は、Err.Number、Err.Descriptionに加え、独自に時刻やSQLを残すと原因追跡が早くなります。
- ログは個人情報やパスワードを含まない形にします。
FAQ:トランザクションはどんな処理で使うべき?
同じ目的の複数更新を一度に確実に反映したいときに使います。たとえば、受注の追加と在庫の更新を同時に成功させたい場合です。読み取りだけの処理では通常不要です。
2. ADODB.Recordsetの使い方(取得・更新・カーソル/ロック)
データの取得や更新にはRecordsetを使います。ここでは、取得方法の選び分け、更新の基本、カーソル/ロックの選択を示します。
Executeで取得する方法(軽量)
結果をすぐ配列にして処理する場合に向きます。
“`vba
Dim rs As Object ‘ ADODB.Recordset
Set rs = cn.Execute(“SELECT id, name FROM users WHERE active = 1”)
Dim data As Variant
If Not rs.EOF Then
data = rs.GetRows() ‘ [列][行] の配列
End If
rs.Close: Set rs = Nothing
“`
- 軽い読み取りに向きます。カーソル種別を細かく制御しない場合に簡単です。
Recordset.Openで取得する方法(制御重視)
カーソルやロックを指定して、スクロールや更新を制御します。
“`vba
Dim rs As Object ‘ ADODB.Recordset
Set rs = CreateObject(“ADODB.Recordset”)
rs.CursorLocation = 3 ‘ adUseClient(推奨:Excel側で扱いやすい)
rs.Open “SELECT id, name FROM users”, cn, 0, 1 ‘ adOpenForwardOnly, adLockReadOnly
Do Until rs.EOF
Debug.Print rs.Fields(“id”).Value, rs.Fields(“name”).Value
rs.MoveNext
Loop
rs.Close: Set rs = Nothing
“`
- ForwardOnly + ReadOnlyは最も軽く、読み取り専用に向きます。
更新系(INSERT/UPDATE/DELETE)
更新は cn.Execute を使うのが簡単です。
“`vba
Dim affected As Long
affected = cn.Execute(“UPDATE users SET active=0 WHERE last_login < DATE_SUB(NOW(), INTERVAL 180 DAY)”).RecordsAffected
“`
トランザクションと組み合わせると安全です(前章参照)。
パラメータ化(安全な書き方)
文字連結でSQLを作ると、意図しない値や記号で失敗しやすくなります。ADODB.Commandでパラメータに値を入れると安全です。
“`vba
Dim cmd As Object ‘ ADODB.Command
Set cmd = CreateObject(“ADODB.Command”)
Set cmd.ActiveConnection = cn
cmd.CommandText = “SELECT id, name FROM users WHERE name LIKE ? AND active = ?”
cmd.CommandType = 1 ‘ adCmdText
cmd.Parameters.Append cmd.CreateParameter(“p1”, 200, 1, 50, “%” & key & “%”) ‘ adVarChar, adParamInput
cmd.Parameters.Append cmd.CreateParameter(“p2”, 11, 1, , True) ‘ adBoolean, adParamInput
Dim rs2 As Object
Set rs2 = cmd.Execute
‘ …処理…
rs2.Close: Set rs2 = Nothing
Set cmd = Nothing
“`
- パラメータ化すると、値のエスケープや型の扱いが安定します。
カーソル種別の比較
| カーソル種別 | 値(定数) | 特徴 | 主な用途 |
|---|---|---|---|
| ForwardOnly | adOpenForwardOnly(0) | 前方向のみ。最軽量 | 一括読み取り、レポート出力 |
| Static | adOpenStatic(3) | スナップショット。スクロール可 | 画面表示で前後移動 |
| Keyset | adOpenKeyset(1) | 主キー集合固定。一部更新可 | 編集フォーム |
| Dynamic | adOpenDynamic(2) | 変化を反映。最も重い | 特殊用途 |
ロック種別の比較
| ロック種別 | 値(定数) | 特徴 | 主な用途 |
|---|---|---|---|
| ReadOnly | adLockReadOnly(1) | 読み取り専用 | レポート、集計 |
| Optimistic | adLockOptimistic(3) | 更新時だけロック | 通常の編集 |
| Pessimistic | adLockPessimistic(2) | 編集中ずっとロック | 競合を確実に避けたい |
| BatchOptimistic | adLockBatchOptimistic(4) | まとめて更新 | オフライン編集 |
迷ったら、読み取りは「ForwardOnly + ReadOnly」、編集は「Keyset + Optimistic」から試すと分かりやすいです。
フィールドアクセスと走査
Fields("列名").Valueで値を読む/書く。EOF/BOFで先頭・末尾を判断。MoveNext/MovePrevious/MoveFirst/MoveLastで移動します。
FAQ:ForwardOnlyとKeysetはどう選ぶ?
読み取りだけで速さ優先ならForwardOnly。画面で行を行き来したり、一部列を更新したいならKeysetが扱いやすいです。最初は軽いForwardOnlyを試し、必要になったらKeysetへ切り替えます。
接続できない場合のチェックリスト(エラー別の確認)
よくあるエラーを、原因の観点で素早く切り分けます。下の表で当てはまるものを確認し、順に潰していきます。
代表エラーと原因の目安
| メッセージ/番号の例 | 主な原因候補 | まず確認すること |
|---|---|---|
| [HY000][1045] Access denied | ユーザー/パスワード不一致、権限不足、ホスト許可なし | 資格情報、ホスト許可、最小権限の確認 |
| [08001] Cannot connect | ホスト名/IP/ポート誤り、Firewall、サーバ停止 | Server/IP、Port=3306、疎通(ping) |
| 0x800A0E7A Provider not found | ODBCドライバ未インストール/bit不一致 | MySQL ODBCの有無、32/64bit一致 |
| Timeout expired | ネットワーク遅延、重いSQL、タイムアウト短すぎ | Index有無、CommandTimeout 設定 |
| Character set関連の文字化け | 文字コード不一致 | 接続オプション、SQL側のCOLLATE |
切り分けの順序
- サーバー疎通:IP直指定で試す。ポート3306を明示する。
- 資格情報:別ツールや社内ツールでログインできるか確かめる。
- ODBCドライバ:コントロールパネルで有無とbit数を確認する。
- 接続オプション:
Option=3を起点に、必要に応じて設定を追加する。 - SQL/権限:SELECTだけ通るか試し、更新は最小の1件で試す。
ログの取り方(再掲)
Err.Number、Err.Description、実行したSQL、時刻を記録します。- 個人情報やパスワードはログに含めないようにします。
画面からもリンクできるよう、問題に応じて前の章へ戻ってください。認証エラーが出る場合は「基本的な接続方法」の接続文字列を見直し、更新の失敗は「ADODB.Connectionのトランザクション」を再確認します。
FAQ:「[HY000][1045]」や「0x800A0E7A」は何を示す?
1045は認証失敗です。ユーザー名/パスワード、接続許可ホスト、権限の見直しをします。0x800A0E7Aはドライバが見つからない場合が多く、ODBCドライバの有無やbit数の不一致を確認します。
安全な書き方と運用のコツ(パラメータ化・設定分離)
安全に長く使うための基本をまとめます。ここは考え方の整理です。
パスワードの扱い
- VBA内に平文で置かない運用が望ましいです。設定ファイルや環境変数の読み込みに分離します。
- 社内規定がある場合はそれに従います。共有ファイルに資格情報を書かないようにします。
最小権限
- 読み取りだけの帳票や集計なら、読み取り専用ユーザーを使います。
- 更新が必要でも、対象スキーマやテーブルを限定した権限にします。
タイムアウトとリトライ
- 一時的な接続失敗には短いリトライを入れると安定します。無限リトライは避けます。
- 重いSQLはサーバー側のインデックスで改善できることがあります。必要なら管理者に相談します。
ログとマスキング
- 失敗時のメッセージとSQLを記録しますが、パラメータ値のうち個人情報はマスクします。
- ログの保存期間や保管場所は、社内ルールに合わせます。
接続数の上限
- 処理が終わったら速やかにCloseします。並列実行を増やしすぎないようにします。
内部リンク:更新系を行うときは、トランザクションの基本も確認してください(本記事内:ADODB.Connectionの使い方)。パスワードの扱いに不安があれば、本章を都度参照してください。
FAQ:接続情報はどこに保存するのがよい?
共有しない個人環境なら、暗号化した設定ファイルに保存する方法があります。共有環境では、資格情報は個人ごとに分け、読み取り権限だけを与えると安全です。具体的な保管方法は社内の情報セキュリティ規程に従います。