Access VBAの「神」になる:テーブル構造変更を安全に守るトランザクション制御の極意
こんにちは。現場で泥臭くシステムを構築し、時に絶望的なエラーと対峙してきたエンジニアの視点から、今日はAccess開発における「禁断の領域」についてお話しします。
皆さんは、VBAでテーブルの列を追加したり、型を変更したりする際、こんな不安を感じたことはありませんか?
「もし、処理の途中でエラーが起きたら、データベースはどうなるんだろう?」
そう、Accessのテーブル構造変更(DDL操作)は、通常のレコード更新とは異なり、一度実行すると「後戻りできない」という恐怖を伴います。今日は、そんな現場の不安を解消する「トランザクション制御」という強力な武器を授けましょう。
—
1. なぜ「テーブル変更」は危険なのか?
通常、レコードの追加や更新(SQLの`INSERT`や`UPDATE`)は、`BeginTrans`と`CommitTrans`で囲むことで、失敗時にロールバック(取り消し)が可能です。
しかし、`TableDef`オブジェクトを使ったテーブル構造の変更(`Fields.Append`など)は、実はAccessのトランザクション管理の対象外となるケースが多いのです。これを知らずに開発を続けると、不完全なテーブル定義が残る「ゴミデータ」の山を築くことになります。
解決策:構造変更とデータ更新の「分離戦略」
構造変更は「失敗させないこと」に全力を注ぎ、変更後のデータ整合性だけをトランザクションで守る。これが、現場で生き残るためのアーキテクチャ設計です。
—
2. 安全なテーブル変更を実現する実践コード
今回は、「テーブルに新しいフィールドを追加し、既存の値を変換する」という、最も事故が起きやすいシナリオで解説します。
Public Sub SafeTableModify()
Dim db As DAO.Database
Dim td As DAO.TableDef
Dim fld As DAO.Field
Set db = CurrentDb
Set td = db.TableDefs(“T_顧客マスター”)
‘ エラーハンドラを仕込む(これが命綱です)
On Error GoTo ErrorHandler
‘ 1. テーブル構造の変更(ここは不可逆な操作です)
‘ フィールドが存在しない場合のみ追加
If Not FieldExists(td, “会員ランク”) Then
Set fld = td.CreateField(“会員ランク”, dbText, 20)
td.Fields.Append fld
End If
‘ 2. データ更新のトランザクション開始
‘ ここからは失敗しても安全に戻せます
db.BeginTrans
‘ データを一括更新
db.Execute “UPDATE T_顧客マスター SET 会員ランク = ‘一般’ WHERE 会員ランク IS NULL”, dbFailOnError
‘ 全て完了したら確定
db.CommitTrans
MsgBox “テーブル更新完了!”, vbInformation
Exit Sub
ErrorHandler:
‘ トランザクションをロールバックして未完了の更新を取り消す
db.Rollback
MsgBox “エラー発生!変更をロールバックしました。” & vbCrLf & _
“エラー詳細: ” & Err.Description, vbCritical
End Sub
‘ 補足:フィールドの有無を確認する便利な関数
Private Function FieldExists(td As DAO.TableDef, fieldName As String) As Boolean
Dim f As DAO.Field
For Each f In td.Fields
If f.Name = fieldName Then
FieldExists = True
Exit Function
End If
Next
FieldExists = False
End Function
—
3. このコードが「プロ仕様」である3つの理由
① `dbFailOnError` の重要性
`db.Execute` の末尾に付けるこのオプションを忘れてはいけません。これがないと、SQLの実行が途中で失敗しても、VBAは「成功した」と勘違いして次の処理に進んでしまいます。エラーを黙殺させないこと、これがシステム安定の第一歩です。
② ロールバックの範囲を最小限にする
構造変更は「変更前」に済ませ、データ操作のみをトランザクションで囲む。この設計により、万が一の際も「構造は変更されたが、データは壊れていない」という、リカバリ可能な状態を維持できます。
③ フィールド存在チェックの徹底
何度も実行される可能性のあるツールでは、「既にフィールドがあるからエラー」という事態を防ぐ必要があります。`FieldExists`関数の有無が、ツールの堅牢性を左右します。
—
先輩エンジニアからのメッセージ
プログラミングを始めたばかりの頃は、「動けばいい」と考えがちです。しかし、本当に恐ろしいのは「動かないこと」ではなく、「中途半端な状態で動いて、後からデータの整合性が壊れること」です。
今回紹介したトランザクション制御とエラーハンドリングは、あなたが書くコードを「おもちゃ」から「業務システム」へと昇華させるための必須スキルです。
怖がらずに、まずは手元の小さな実験用データベースで試してみてください。ここをクリアすれば、あなたはもうAccess VBAの初級者を卒業し、中級者への階段を確実に登っていますよ。
何か分からないことがあれば、いつでも聞いてください。一緒に最高のシステムを作り上げましょう。
