【入門編】Access VBAにおける「トランザクション」とQueryDefの併用 – Access VBA解析バイブル

スポンサーリンク

Access VBAの深淵へ:QueryDefとトランザクションで「データの整合性」を完璧に守る技術

こんにちは。自動化の現場で修羅場をくぐり抜けてきた皆さんに、今日は「Access VBAにおけるデータベース操作の真髄」をお話しします。

マクロの記録から卒業し、本格的な業務システムを構築しようとすると、必ずぶつかる壁があります。それは「複数の更新処理を、失敗した時にまとめて元に戻したい(ロールバックしたい)」という切実な要求です。

「クエリを順番に実行すればいいのでは?」と思ったあなた。実は、それだけでは不十分です。もし途中で停電したり、エラーが発生したりしたら? データは中途半端な状態で放置され、現場は大混乱に陥ります。

今日は、`QueryDef`による動的クエリ実行と、`Transaction`(トランザクション)を組み合わせた、プロ仕様のデータ更新術を伝授します。

—

1. なぜ「トランザクション」が必要なのか?

トランザクションとは、「一連の処理を『ひとまとめの塊』として扱う仕組み」です。

  • コミット (Commit): 全ての処理が成功したら、一気に確定する。
  • ロールバック (Rollback): 一つでも失敗したら、なかったことにする。

これを制御するのが、DAO(Data Access Objects)の`Workspace`オブジェクトです。

—

2. 実践コード:安全な更新処理のテンプレート

以下は、トランザクションを用いて安全にクエリを実行する黄金パターンです。この構造をマスターすれば、データ不整合の恐怖から解放されます。

Public Sub SafeUpdateTransaction()
Dim ws As DAO.Workspace
Dim db As DAO.Database
Dim qdf As DAO.QueryDef

‘ デフォルトのワークスペースを取得
Set ws = DBEngine(0)
Set db = CurrentDb

‘ トランザクション開始
ws.BeginTrans

On Error GoTo ErrorHandler

‘ — クエリ処理1 —
Set qdf = db.QueryDefs(“qUpd_Inventory”)
qdf.Parameters(“prmStock”) = 100
qdf.Execute dbFailOnError ‘ dbFailOnErrorを必ずつけるのがプロの流儀

‘ — クエリ処理2 —
Set qdf = db.QueryDefs(“qUpd_SalesLog”)
qdf.Parameters(“prmDate”) = Date
qdf.Execute dbFailOnError

‘ 全て成功したら確定
ws.CommitTrans
MsgBox “更新が正常に完了しました。”, vbInformation

ExitPoint:
Set qdf = Nothing
Set db = Nothing
Exit Sub

ErrorHandler:
‘ 何か一つでも失敗したら元に戻す
ws.Rollback
MsgBox “エラーが発生したため、処理を中断しロールバックしました。” & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical
Resume ExitPoint
End Sub

—

3. なぜ `dbFailOnError` が不可欠なのか?

ここが初心者と中級者の分かれ道です。
`qdf.Execute` を実行する際、引数に `dbFailOnError` を付け忘れてはいけません。

これを付けないと、Accessは「クエリが失敗してもエラーを投げずに無視する」という挙動をとることがあります。つまり、失敗したことに気づかないまま `CommitTrans` が走ってしまうのです。これではトランザクションの意味がありません。`dbFailOnError` を指定することで、エラー発生時に確実に `ErrorHandler` へ飛ばすことができます。

—

4. 陥りやすい罠と対策

① フォームを開きっぱなしにしない

トランザクション中にフォームを開いていたり、他の処理が走っていたりすると、ロックが競合して「リソースが使用中です」というエラーが出ることがあります。処理中は極力、単独で静かに動かすのが鉄則です。

② `QueryDef` の再利用性

`QueryDef` は、クエリ作成時にパラメータを指定しておくことで、動的なSQLとして強力な力を発揮します。VBA内でSQLを文字列結合して作成する(`”SELECT FROM table WHERE ID = ” & id`)のは、SQLインジェクションのリスクがあるため推奨しません。必ず名前付きパラメータ(`[prmID]`など)を使いましょう。

—

先輩エンジニアからのメッセージ

皆さんが書くコードは、単なる命令の羅列ではありません。「業務の信頼性」を守るための盾です。

「もしここでエラーが起きたら?」という想像力を働かせること。それが、開発者として一段上のステージに上がるための唯一の道です。このトランザクションのコードをテンプレートとして保存し、ぜひ現場のシステムに組み込んでみてください。

ここをクリアしたあなたは、もう「マクロ書き」ではありません。立派な「データベース・アーキテクト」への第一歩を踏み出したのです。何か分からないことがあれば、いつでも聞いてくださいね。応援しています。

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