motogp fan

motogp ファンによる、モトgp 結果、モトgp日程を報告するブログ、ガジェットネタも

Access 実行時エラー 3052 解決方法 コミットせよ

Accessアプリ*1の、月締め処理を6ヶ月間の範囲指定に改造したら、
実行時エラー 3052 が発生して動かなくなった。
f:id:motagp:20150522105752j:plain

ファイルの共有ロック数が制限を超えています(Error 3052)。
って、なんだよこれ、一人でしか使わないシステムだけど。
共有してないよ・・・・

 

Microsoftの技術情報
多数のトランザクション処理中にエラー メッセージ "ファイルの共有ロック数が制限を超えています" が表示される

 

トランザクションとかかけてないし、何??
資料見ると
「方法 1 : MaxLocksPerFile レジストリ キーを設定して、ファイルごとの最大ロック数を増やす」
おいおい、このアプリ導入している端末全部変えるの?無理あるよね。

「方法 2 : SetOption メソッドを使用して MaxLocksPerFile の値を一時的に変更する」
これこれ、試しました。
規定値が9500なので倍にしたけど駄目。
30000に変更したら、Windows2008R2+Access2007で動作。
でもWindows7+Access2007では同じエラー、さらに40000へアップ。
やっと動きました!


VBAに追加したコードはこれです。
  DBEngine.SetOption dbMaxLocksPerFile, 40000

 

[2015/5/23追記]

注、この記事を読んだ先輩から、下記アドバイス貰いました。

Accessでは勝手にトランザクション処理が動いていて、初期値9500件を超えると、3052エラーが発生するそうです。
対処方法は、安易に最大値を増やすのではなく、定期的にコミットする事。 

変更したコードが下記です。(赤色追記)

Dim intTranCount AS integer
Set rsOut = dbCUR.OpenRecordset("SELECT * FROM OXテーブル")

intTranCount = 0
DBEngine.BeginTrans

Do While Not rsOut.EOF
 rsOut.Edit
 rsOut(21).Value = rsOut(10).Value
 rsOut.Update
 rsOut.MoveNext
 'トランザクションMAX制御
 intTranCount = intTranCount + 1
 If intTranCount = 5000 Then
  DBEngine.CommitTrans
  DBEngine.BeginTrans
  intTranCount = 0
 End If
Loop
DBEngine.CommitTrans
rsOut.Close

 

気のせいか速度も速くなった様な・・・
ありがとうございました。

 

www.timsoft.co.jp

*1:4万件のデータを作成し集計するアプリ