【入門編】DoCmd.RunSQLとCurrentDb.Executeの使い分け:トランザクション制御の決定版 – Access VBA解析バイブル

スポンサーリンク

こんにちは!現場でバリバリ使えるAccess VBAを一緒に極めていきましょう。

マクロの記録から一歩踏み出し、「自分でコードを書いてシステムをコントロールしたい!」そう思った瞬間が、エンジニアとしての本当のスタートです。

今回は、Access VBAでデータを更新・追加・削除する際になくてはならない「SQLの実行方法」について、プロの現場でも必ず議論になる超重要テーマを解説します。

具体的には、`DoCmd.RunSQL` と `CurrentDb.Execute` の違い、そして実務で絶対に避けて通れない「トランザクション制御(エラー時のロールバック)」の本質に迫ります。ここをクリアすれば、あなたのAccess開発スキルは間違いなくワンランク上のステージに到達しますよ。

1. 導入:なぜ「データの書き換え」で悩むのか?

AccessでVBAを使ってテーブルのデータを操作するとき、あなたならどちらの書き方を選びますか?

  • パターンA: `DoCmd.RunSQL “UPDATE …”`
  • パターンB: `CurrentDb.Execute “UPDATE …”, dbFailOnError`

「どっちでも動くなら、短い方でいいや」なんて思っていませんか?
実は、ここには「システムの信頼性を左右する決定的な違い」があります。

初学者のうちは「画面がパッと動いてエラーが出なければいいや」と思いがちですが、実際の業務では「途中でエラーが起きたら、書きかけのデータを全部なかったことにしたい(ロールバック)」という要件が必ず出てきます。

この要件をスマートに、かつ確実に満たすための極意を、順を追って優しく解きほぐしていきますね。

2. 基本の整理:DoCmd.RunSQL と CurrentDb.Execute の正体

まずは、それぞれの特徴をエンジニアの視点で整理しておきましょう。

① DoCmd.RunSQL(マクロの魂を引き継ぐUI連動型)

  • 正体: Accessの画面(UI)の裏側で、ユーザーが操作しているかのようにSQLを実行するメソッドです。
  • 特徴:
  • 実行時に「〇件のレコードを追加します」といった確認メッセージ(警告)が勝手に画面に出てきます
  • これを消すには `DoCmd.SetWarnings False` を事前に書く必要があります。
  • エラーハンドリングが少し弱いです。

② CurrentDb.Execute(データベースエンジン直結の高速・堅牢型)

  • 正体: Accessの心臓部であるDAO(Data Access Objects)を通じて、データベースエンジンに直接SQLを投げ込むメソッドです。
  • 特徴:
  • 警告メッセージは最初から一切出ません。(静かでスマート!)
  • `dbFailOnError` というオプションを付けることで、SQLの途中でエラーが起きたときに即座に処理を中断し、エラーを検知できます。

【結論】
特別な理由がない限り、VBAコード内でのデータ更新は `CurrentDb.Execute` を使うのがプロの常識 です。

3. 実践!トランザクション制御の決定版コード

ここからが本題です。
例えば、「売上テーブルにデータを追加しつつ、在庫テーブルの数値を減らす」という処理を考えてみてください。

もし、売上の追加が終わった瞬間に電源が落ちたり、エラーが発生したりしたらどうなるでしょう?
売上だけが増えて、在庫が減らないという「データの整合性が崩れた最悪の状態(バグ)」が生まれてしまいます。

これを防ぐのが トランザクション(BEGIN / COMMIT / ROLLBACK) です。
「一連の処理はすべて成功するか、すべて失敗(なかったこと)にするか、どちらかにする」という鉄の掟です。

以下のコードを、あなたの開発現場の標準テンプレートとして持っておいてください。

Public Sub ExecuteWithTransactionSample()
Dim db As DAO.Database
Dim sql1 As String
Dim sql2 As String

‘ 1. 現在のデータベースへの参照を取得(パフォーマンス向上のお作法)
Set db = CurrentDb()

‘ 2. トランザクションの開始(ここから安全ネットが張られます)
db.BeginTrans

On Error GoTo ErrorHandler ‘ エラーが発生したらErrorHandlerラベルにジャンプ

‘ — 処理①:売上データの追加(例) —
sql1 = “INSERT INTO T_売上 (商品ID, 数量, 売上日) VALUES (101, 5, Date());”
db.Execute sql1, dbFailOnError

‘ — 処理②:在庫データの減算(例) —
sql2 = “UPDATE T_在庫 SET 在庫数 = 在庫数 – 5 WHERE 商品ID = 101;”
db.Execute sql2, dbFailOnError

‘ 3. すべての処理が成功した場合、変更を確定(コミット)
db.CommitTrans

MsgBox “すべての処理が正常に完了しました!”, vbInformation, “成功”
GoTo Finally

ErrorHandler:
‘ 4. 万が一エラーが発生した場合、処理をすべて巻き戻す(ロールバック)
db.RollbackTrans

MsgBox “エラーが発生したため、処理を中断し変更を元に戻しました。” & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical, “異常終了”

Finally:
‘ 5. オブジェクトの解放(メモリ管理の基本)
Set db = Nothing
End Sub

4. コードの深掘り:なぜこの書き方が「最強」なのか?

上記のコードには、Access VBAを極めたエンジニアのこだわりが詰まっています。ポイントを3つに分けて解説しますね。

Point 1: `Set db = CurrentDb()` の一手間

コード内で何度も `CurrentDb.Execute` と書く代わりに、一度 `Set db = CurrentDb()` で変数に受けています。
実は、`CurrentDb` という関数は呼び出すたびに内部でデータベースへの接続オブジェクトを新しく生成し直しています。変数に保持させて使い回すことで、圧倒的な処理の高速化とメモリの無駄遣い防止につながります。

Point 2: `dbFailOnError` の指定

`db.Execute sql, dbFailOnError` のように、第2引数に `dbFailOnError` を必ず指定してください。
これがないと、SQLの途中でエラー(主キーの重複や型の不一致など)が発生しても、Accessは「シラッ」と何食わぬ顔で次の処理に進んでしまい、エラーをキャッチできなくなります。エラーを確実に検知してロールバックに繋げるための必須パーツです。

Point 3: BeginTrans と RollbackTrans のペア

銀行のATMでお金を下ろすとき、機械から現金が出てくる前に通信エラーが起きたら、口座残高が減っていたら大問題ですよね。それと同じで、複数のSQLがワンセットの業務は、必ず `BeginTrans` で囲み、失敗したら `RollbackTrans` で無かったことにする。この安全意識が、信頼されるシステムを作ります。

5. よくあるつまずきポイント(Q&A)

Q. トランザクションを使えないSQLがあるって本当?

A. はい、一部あります。
`CREATE TABLE` や `DROP TABLE` などの「データ定義言語(DDL)」と呼ばれるテーブル構造自体を変更するクエリは、トランザクションのロールバック対象外となることが多いです。
トランザクションが確実に威力を発揮するのは、今回紹介したようなデータの追加・更新・削除(DML)の領域です。

Q. エラー処理の `On Error GoTo` を書き忘れるとどうなる?

A. トランザクションが開きっぱなしになります。
VBAのコード内でエラーが起きた際、`RollbackTrans` が実行されないままプログラムが中断すると、Accessのファイル内にロックが残り続け、最悪の場合ファイルが破損したり他のユーザーが操作できなくなったりします。エラーハンドラー(`On Error GoTo`)はトランザクションを使うときの命綱です。必ずセットで書きましょう。

まとめ:ここをクリアすれば、Access VBAは怖くない!

今回は、`DoCmd.RunSQL` と `CurrentDb.Execute` の違いから、実務で必須となるトランザクション制御までを解説しました。

  • メッセージを出さずに安全にSQLを実行したいなら `CurrentDb.Execute` + `dbFailOnError`
  • 複数の更新処理を安全に行うなら `BeginTrans` と `RollbackTrans`

この2つをマスターすれば、もう「マクロのノリ」でコードを書く必要はありません。あなたは確実なロジックでデータを守る、立派なアプリケーション開発者です。

日々の開発でぜひこのテンプレートを活用し、堅牢で美しいAccessシステムを作り上げてくださいね。応援しています!

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