誰も使っていないのに...

ある人が、Accessでフォームをつくっていました。(仮にAさんとします)
伝票入力のフォームなので、データ修正中は他の人にいぢられては困ると、フォームの「レコードロック」プロパティ「編集済みレコード」に設定しました。


 

単価を伝票ごとに保持する必要があったので、伝票テーブルには「単価」項目と「金額」項目があります。Aさんは、「単価」「商品マスタ」に登録されていますから、最新の単価をとってきて伝票テーブルを自動で更新しようと考えました。まぁこんなのよくある処理ですな。
で、商品コードの更新後処理イベントにこんなモジュールを書きました。

Dim Mydb As Database
Dim MyRS as Recordset

Set Mydb = Currentdb()
Set MyRS = Mydb.OpenRecordset("select * from [伝票] where [伝票番号]=" & me![伝票番号])
With MyRS

.Edit
.Fields("単価") = DlookUP("単価","商品マスタ","商品コード =" & me![商品コード])
.Fields("金額") = .Fields("単価") * me![数量]
.Update

End With
MyRS.close
Mydb.close

ところが、商品コードを変更すると、奇妙なエラーが発生するのです。

「実行時エラー'3188': このマシンのほかのセッションによってロックされているので、更新できませんでした。」

...あれ?
自分のマシンを確認しましたが、他にAccessが立ち上がっている様子もありません。MDB が入っているフォルダは自分のマシンにあり共有設定もしていませんから他から開くことはできないはず。MDB が壊れたかと修復・最適化・新規 MDB へのインポートも当然試しましたが効果はありません。

一体なぜ、誰も使っていないのに、ロックされてしまっているんでしょう?
この MDB は呪われてしまったのでしょうか?この後どうしたらいいんでしょうか?



...いや別に呪われてはいないでしょう(^_^;) 壊れやすい MDB なんかは呪われてると思いたくもなりますが、今回の場合はそれとも違いますね。

問題は、フォームの中から、フォームのレコードソースになっているテーブルを、モジュールを使って更新しようとしたことにあります。
フォームのレコードソースになっているテーブルは、フォームによって更新データがロックされます。そのロックのやり方を指定するのが、最初に出てきたフォームの「レコードロック」プロパティです。
今回の場合、これを「編集済みレコード」に指定していますので、フォームのレコードセレクタ「えんぴつマーク」(どこかの連結コントロールの内容が変更された状態)になっている場合、フォームによって該当ページがロックされます。 え?そんなの判ってる?判ってて指定してるんだ?まぁそう言わずに(^_^;)

実は、モジュールによる更新は、連結フォームのそれとは別セッションになります。

ぜんぜん別のフォームや別のモジュールから実行してれば同じセッションとは思わないでしょうから、こんなカンチガイはしなくて済むのですが、フォームのイベントプロシージャに記述したりすると、うっかり同一セッションと思い込んでしまうこともあります。(当然ですが、別フォームや別モジュールからの更新を含めすべて別セッション扱いになります)
フォームの「レコードロック」プロパティ「しない」にすればメッセージは出なくなりますが、それでは排他制御の問題が残りますのでここは変更するべきではありません。

んじゃ、こんなときAさんはどうしたらいいんでしょう?

こたえは簡単。モジュールから更新できないんだったら、フォームの連結コントロールを利用すればよいのです。これなら当然同一セッションになります。
Aさんの場合ですと、フォーム上に非表示でもいいから、[単価]、[金額]項目と連結しているコントロールを用意し、そこへ値をセットしてあげればいいのです。

me![単価] = DlookUP("単価","商品マスタ","商品コード =" & me![商品コード])
me![金額] = me![単価] * me![数量]

こうすれば、修正したレコードが保存されるタイミングで単価、金額がいっしょに保存されます。セットするタイミングは、商品コード等の更新後処理でもいいですし、フォームの更新前処理でもいいでしょう。
モジュールで先に変更して保存してしまうと、商品コードに対する変更がキャンセルされても単価と金額は変わってしまったりと不都合が生じますので、そういう意味でもモジュールで別更新することは避けたほうがいいと言えます。
どうも、「自動で更新」というコトバから、ついついモジュールでレコードセットとか更新クエリーで一括更新とか考えてしまいがちですが、「更新」手段はそれだけではないということですね。

トラックバック(0)

トラックバックURL: http://www.naboki.net/movabletype/mt-tb.cgi/37

Access 心霊体験集

誰も使っていないのに...

The items might be used by nobody

何故、自宅のマシンでは

Why don't work the MDB in my home PC!? No way!

このアプリケーションは不正な処理を実行しました

This application has performed an illegal operation and will be terminated.

勝手にデータが置き換わる!

The data has been changed automatically!

見えない何かが、いる。

Something is there which I cannot see it

MSDN クラウド 技術解説コミック新登場 クラウド ガール - 窓と雲と碧い空 -