こんにちは!Access VBAの世界へようこそ。
日々、フォームやマクロから脱却し、本格的なデータベースアプリを作ろうと奮闘されていることと思います。
今回は、Accessを「フロントエンド」、SQL Serverなどを「バックエンド」にした、いわゆるクライアント/サーバー型(C/S型)システムを構築する上で、避けて通れない非常に重要なテーマを取り上げます。
それが、`CurrentDb.Execute`メソッドにおける「`dbSeeChanges`」オプションです。
「なんだか難しそうな名前だな……」と思いましたか? 大丈夫です。ここをしっかりと理解すれば、現場でよくある「謎のエラー」に頭を悩ませることがなくなりますよ。優しく、本質から紐解いていきましょう!
—
1. なぜ「SQL Server連携」だと話が変わるのか?
私たちが普段何気なく使っているAccessのテーブル(ローカルテーブル)は、Access自体がデータを管理しています。そのため、VBAでデータを追加・更新するときは、あまり細かいことを気にする必要がありませんでした。
しかし、バックエンドに SQL Server などの本格的なRDBMS(リレーショナルデータベース管理システム)を据えた瞬間、世界のルールが変わります。
SQL Serverなどの外部データベースは、複数のユーザーが同時にアクセスしてデータを書き換えることを前提としています。そのため、Access側から「このデータを書き換えて!」と命令したとき、SQL Server側で「おっと、今ほかの誰かがこのデータを触ったかもしれないから、そのまま上書きするのは危険だぞ!」と検知する仕組み(オプティミスティック同時実行制御)が働きます。
この仕組みのせいで、Access VBAからINSERTやUPDATEを実行した際、「更新の競合」エラーという、初心者泣かせの壁にぶつかることになるのです。
—
2. 救世主 `dbSeeChanges` の正体
ここで登場するのが、今回の主役である `dbSeeChanges` です。
VBAでSQLを実行する際、`CurrentDb.Execute` の第2引数にこのオプションを指定します。
CurrentDb.Execute “SQL文”, dbSeeChanges
このオプションの意味を日本語で翻訳すると、こうなります。
「ねえAccessさん、裏でSQL Serverが動いているのは分かっているよ。だから、データの変更が他のプロセスとバッティングしていないか(競合がないか)ちゃんと監視しながら実行してね!」
この `dbSeeChanges` をつけ忘れると、SQL Server連携のテーブルに対して追加・更新を行った瞬間、容赦なくエラーが発生してVBAが止まってしまいます。
—
3. 【実践】正しいコードと間違えやすいコード
百聞は一見に如かず。実際のコードを見てみましょう。
ここでは、SQL Serverに接続された「T_顧客」テーブルに、VBAから新しい顧客データを追加するシーンを想定します。
❌ やってしまいがちングなコード(エラーになる例)
Sub UpdateCustomer_Bad()
Dim strSQL As String
strSQL = “INSERT INTO T_顧客 (顧客名, 担当者) VALUES (‘株式会社未来工業’, ‘佐藤 健’);”
‘ ▼ローカルテーブルのノリで実行すると、SQL Server連携時はエラーになります!
CurrentDb.Execute strSQL
MsgBox “登録完了しました!”, vbInformation
End Sub
【結末】
バックエンドがSQL Serverの場合、このコードを実行すると実行時エラー(「更新可能なレコードセットを使用する必要があります」や「更新の競合」など)が発生し、プログラムがプツンと途切れてしまいます。
⭕ 正しいプロのコード(`dbSeeChanges` を添えて)
Sub UpdateCustomer_Good()
Dim strSQL As String
On Error GoTo ErrorHandler
‘ 追加するSQL文を組み立てる
strSQL = “INSERT INTO T_顧客 (顧客名, 担当者) VALUES (‘株式会社未来工業’, ‘佐藤 健’);”
‘ ▼【重要】第2引数に dbSeeChanges を指定する!
CurrentDb.Execute strSQL, dbSeeChanges
MsgBox “データを正常に登録しました!”, vbInformation
Exit Sub
ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
End Sub
たったこれだけのことですが、`dbSeeChanges` というおまじない(正確には定数)を添えるだけで、SQL Serverの厳しいチェックルールをクリアし、安全にデータを書き込むことができるのです。
—
4. どんなときに `dbSeeChanges` が「必須」になるのか?
すべてのSQLでこのオプションが必要なわけではありません。以下の条件が揃ったときに必須となります。
1. バックエンドが外部データベース(SQL Server, Azure SQL Databaseなど)である場合
2. `CurrentDb.Execute` を使って、データの「追加 (INSERT)」「更新 (UPDATE)」「削除 (DELETE)」を行う場合
※なお、単にデータを「参照 (SELECT)」するだけの `OpenRecordset` や `SELECT` クエリでは、基本的には不要です(ただし、レコードセットの更新を行う場合は同様に `dbSeeChanges` が必要になることがあります)。
—
まとめ:ここをクリアすれば基本はバッチリ!
今回は、Access VBAとSQL Serverを連携させる際の最大の関門、「更新の競合」と `dbSeeChanges` について解説しました。
- ローカルテーブル感覚で `CurrentDb.Execute` を使うと、SQL Server連携時にはエラーになる。
- その原因は「更新の競合」を回避するための安全装置が働くから。
- 解決策として、第2引数に必ず `dbSeeChanges` を指定する習慣をつけよう。
マクロの記録や、ただ動くだけのコードから一歩抜け出して、こうした「データベースの裏側の挙動」まで意識できるようになると、あなたはもう立派な業務システムエンジニアです。
ここをしっかりとクリアできれば、AccessとSQL Serverを組み合わせた堅牢で実用的なシステムの構築は怖くありません。ぜひ、あなたの開発現場でも試してみてくださいね。応援しています!
