こんにちは、なかぜんです。
Accessをマルチユーザーで運用していると、こんなお悩みありませんか?
- 「突然『他のユーザーが編集中です』というエラーが出て保存できない」
- 「排他エラーが怖くてVBAでの更新処理が組めない」
- 「どのロックレベルを選べばよいのか分からない」
こうしたトラブルを防ぐ鍵は、DAOによる適切なレコードロックと排他制御にあります。
この記事では、DAOによる排他制御の基本から、エラー処理付きの実践的なコード、そして応用テクニックまでを、Access/VBA上級者向けにやさしく、かつ業務で役立つように解説していきます。
1. DAOでのレコードロックの基本をおさらい
DAOとは?
DAO(Data Access Objects)は、Accessが標準で持つデータ操作用オブジェクトモデルで、ローカル/共有DBの細やかな制御が得意です。
ロックタイプの種類
- dbOptimistic:実際に
.Update
が呼ばれるまでロックされない(最も一般的) - dbPessimistic:レコード取得時にロック(他ユーザーの更新を防ぐ)
- dbReadOnly:読み取り専用
2. 実践:排他制御を意識した更新処理のコード例
基本的な更新コード(dbPessimistic使用)
Sub UpdateWithLock()
Dim db As DAO.Database
Dim rs As DAO.Recordset
On Error GoTo ErrHandler
Set db = CurrentDb()
Set rs = db.OpenRecordset("T_商品マスタ", dbOpenDynaset, dbPessimistic)
rs.FindFirst "商品コード = 'A001'"
If Not rs.NoMatch Then
rs.Edit
rs!商品名 = "高級チョコレート"
rs.Update
MsgBox "更新完了しました!"
Else
MsgBox "該当レコードが見つかりませんでした。"
End If
ExitHandler:
rs.Close: Set rs = Nothing
Set db = Nothing
Exit Sub
ErrHandler:
MsgBox "エラーが発生しました:" & Err.Description
Resume ExitHandler
End Sub
ポイント:
dbPessimistic
を指定することで、他のユーザーによる同時編集をブロック- 更新前に
FindFirst
で対象レコードを特定 - エラー時には必ずオブジェクト解放処理を
3. よくあるトラブルと対処法
「他のユーザーがレコードをロック中」の対処
このエラーは、対象レコードが既に誰かによりEdit
されている状態で発生します。VBAで対策するには以下のような工夫が必要です:
- Try-Catch的に
On Error Resume Next
で編集可能かチェック - ロック検出時は数秒待って再試行(リトライ制御)
リトライ付きの例
Sub UpdateWithRetry()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim i As Integer
Const RETRY_LIMIT = 3
Const WAIT_MS = 1000
On Error GoTo ErrHandler
Set db = CurrentDb()
For i = 1 To RETRY_LIMIT
Set rs = db.OpenRecordset("T_商品マスタ", dbOpenDynaset, dbPessimistic)
rs.FindFirst "商品コード = 'A001'"
If Not rs.NoMatch Then
On Error Resume Next
rs.Edit
If Err.Number = 0 Then
rs!商品名 = "新しい商品名"
rs.Update
MsgBox "更新成功"
Exit For
Else
MsgBox "ロック中、再試行します…(" & i & "回目)"
Err.Clear
Sleep WAIT_MS ' APIでスリープ(別途宣言必要)
End If
End If
rs.Close: Set rs = Nothing
Next
ExitHandler:
On Error Resume Next
If Not rs Is Nothing Then rs.Close: Set rs = Nothing
Set db = Nothing
Exit Sub
ErrHandler:
MsgBox "エラー発生:" & Err.Description
Resume ExitHandler
End Sub
4. 排他制御を活かす応用テクニック
フォームの連動更新時の排他対策
サブフォームや複数画面で同一レコードを扱う場合、自作のロック制御を用いる方法もあります。
- ロック状態を別テーブルで管理(例:T_ロック管理)
- 更新時に対象レコードの排他権を先取り
「ロック管理テーブル」例
Sub CheckLockBeforeUpdate()
If DCount("*", "T_ロック管理", "商品コード='A001'") > 0 Then
MsgBox "他のユーザーが編集中です。"
Exit Sub
End If
' ロック取得
CurrentDb.Execute "INSERT INTO T_ロック管理 (商品コード, ユーザー名) VALUES ('A001', 'なかぜん')"
' 更新処理実施...
' 最後にロック解除
CurrentDb.Execute "DELETE FROM T_ロック管理 WHERE 商品コード='A001'"
End Sub
5. まとめと次のステップ
今回は、DAOでのレコードロックと排他制御について、次の内容を学びました。
- DAOのロックモード(Optimistic/Pessimistic)の違い
- 排他エラーを防ぐコード例と対策
- リトライ処理やロック管理テーブルを活用した応用テクニック
Accessのマルチユーザー環境では、レコードロックの理解がトラブル防止のカギになります。ぜひ、ご自身のシステムにも取り入れてみてください。
それでは、またお会いしましょう。なかぜんでした😊
¥2,992 (2025/05/24 20:57時点 | Amazon調べ)
