|
遅くなりました
247b さん ありがとうございます
>DT.MDBがサーバー配置になるなら、確かにリンクテーブルの使用は微妙なラインです。
なんですが
>>非連結にしましたが、
>>結局、フォームを開くとき、
>>コントロールのレコードソースを設定しているのでリンクテーブル有り同じことに
>>なっているのではと思っています
やはり、上記のような理解になってしまうのですが
別途何か注意事項等あればコメント頂けるとうれしいです
よろしくお願いいたします
>要件としてはこんな感じでしょうか。
ありがとうございます
勉強になります
>なので、いわゆる排他制御が必要ということですね。
>であれば、前回挙げておられたURLのプログラムソースが参考になると思います。
の
>><ADOを使ったレコード単位の排他ロックについて>
>>tp://www5f.biglobe.ne.jp/~f-lap/tips_adolock.htm
ですが、いまいち・・・?で
ページ レベル ロックとレコード レベル ロック
tp://msdn.microsoft.com/ja-jp/library/cc376645.aspx
ありがとうございます
等あたり他見ているうちに
VBA の Recordset オブジェクトで共有データをロックする
tp://msdn.microsoft.com/ja-jp/library/cc376533.aspx
に
排他モード
共有モード
レコードセット ロック
レコード レベル ロックまたはページ レベル ロック
のサンプルコードがありました
上記について一応動作させることだけは出来たのですが下記よくわかりません
アドバイス頂けると助かります
よろしくお願いいたします
レコードセット ロック DAOOpenTableExclusive
についてですが
DT.MDBが編集中で無ければ問題は無く、テーブル排他で開けましたが
DT.MDBの競合テーブルが編集中の場合(手動で開いて編集)
Set rst = dbs.OpenRecordset(strRstSource, _
dbOpenTable, dbDenyRead + dbDenyWrite)
でとまってしまいました
そこで下記のようにエラー処理を追加してみました
Call DAOOpenTableExclusive("\\hoge\DT.mdb","テーブル名")
で実行
Function DAOOpenTableExclusive(strDBPath As String, _
strRstSource As String) As DAO.Recordset
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
Dim cnt As Integer '登録チャレンジ回数
cnt = 0
On Error GoTo ErrorHandler
' DAOOpenDBShared を呼び出して
' データベースを共有モードで開きます。
Set dbs = DAOOpenDBShared(strDBPath)
' データベースが共有モードで開いたことを確認します。
' 開いた場合、指定したテーブルを排他的に開きます。
If Not dbs Is Nothing Then
'※追記1
'strRstSourceが開かれていると
'実行時エラー '3262': テーブル 'DT' は、マシン 'huga' のユーザー 'Admin' によって使用されているので、ロックできませんでした。
'で停止してしまう
'↓ココでエラーで止まる!!
Set rst = dbs.OpenRecordset(strRstSource, _
dbOpenTable, dbDenyRead + dbDenyWrite)
' レコードセットが開いたことを確認します。開いた場合、
' Recordset オブジェクトを返します。開かなかった場合、Nothing を返します。
If Not rst Is Nothing Then
Set DAOOpenTableExclusive = rst 'レコードセット ロックで開いている
※追記2
'追加しないと ldb.MDBが残る
Set rst = Nothing
Set dbs = Nothing
Else
Set DAOOpenTableExclusive = Nothing
Set rst = Nothing
Set dbs = Nothing
End If
Else
'Set OpenTableExclusive = Nothing
Set DAOOpenTableExclusive = Nothing
Set rst = Nothing
Set dbs = Nothing
End If
Exit Function
ErrorHandler:
If Err.Number = 3262 Then
'MsgBox "エラーです"
'MsgBox "ターゲットテーブルは排他ONで使用中です"
'MsgBox Err.Description 'テーブル 'DT' は、マシン 'hoge' のユーザー 'Admin' によって使用されているので、ロックできませんでした。
'動作良好そう
'ループかタイマで待機 駄目なら 時間を置いて と 思うが 動作的に 複数台のPCが ココでバッティングしたらどうなるのか自信がない
'排他で開いていたら3回チャレンジして中止
If cnt = 4 Then
Set rst = Nothing
Set dbs = Nothing
MsgBox "ファイルが使用中か不具合が発生している可能性があります 時間を置いて登録できないときは管理者に連絡してください"
Exit Function
End If
cnt = cnt + 1
Else
MsgBox "エラー " & Err.Number & " _ " & Err.Description & " が発生しました"
Set rst = Nothing
Set dbs = Nothing
Exit Function
End If
Resume
End Function
Function DAOOpenDBShared(strDBPath As String) As DAO.Database
' このプロシージャには、Micrsoft DAO 3.6 オブジェクト ライブラリへの参照が
' 必要です。このプロシージャは、データベースを共有モードで開けるかどうかを
' 調べます。開けない場合は Nothing を返します。
' レコードセット ロックをインプリメントする場合、このプロシージャで
' データベースを共有モードで開くことができます。
'
' 引数 :
' strDbPath : データベースへのパスです。
'
' 戻り値 :
' 共有モードで開かれているデータベースを参照する Database オブジェクトです。
Dim dbs As DAO.Database
On Error Resume Next
' データベースを開きます。
Set dbs = DAO.OpenDatabase(strDBPath, False)
' エラーを確認します。
If Err <> 0 Then
MsgBox "Cannot open database in shared mode. " & _
vbCr & Err.Description
' Nothing を返します。
Set DAOOpenDBShared = Nothing
Else
' データベースへの参照を返します。
Set DAOOpenDBShared = dbs
End If
End Function
Q1-1
上記で一応動作するのですが、エラー処理等自信がありません
添削、アドバイス等頂けるとうれしいです
Q1-2
下記レコード レベル ロックまたはページ レベル ロックの動作が理解しきれていないので
場合によってはこのコードでもいけそうな気がしています
多分、更新作業も瞬時だろうし、テーブル排他のため、データの競合も発生しないので
よさげな気がしますが、APP.MDBからのフォームの参照が切れてしまうような気がしますが
まだ試していません
この辺、駄目とかいけそうとかアドバイス頂けると助かります
よろしくお願いいたします
レコード レベル ロックまたはページ レベル ロック UpdateUnitsInStock
についてですが
アクセス付録のNwind.mdbをコピーして使用
サンプルコード内でNwind.mdbフルパス、テーブル名指定
Function UpdateUnitsInStock(strProduct As String, _
intUnitsInStock As Integer, _
intMaxTries As Integer) As Boolean
は
strProduct は Product Name 列で 商品選択
Units In Stock は 更新DT値
intMaxTries は 回数 指定
CALL UpdateUnitsInStock("Chang","33","5")
で実行
Q2-1
うまく intMaxTries の動作を チェックすることが出来ません
intMaxTries の デバッグ を するにはどうすればいいでしょうか
Q2-2
別マシンでDT.MDBのProductsを開いていても
上記を実行すると数秒、別マシンのレコードが自動更新されて再表示されます
次に、別マシンでDT.MDBのProductsを開いて Units In Stock を 編集し
上記を実行し、別レコードに移動すると
データの競合 の ダイアログが表示され
"レコードの保存"、"クリップボードにコピー"、または "他のユーザーによる変更を反映"
のオプションが表示されます
これは
>><ADOを使ったレコード単位の排他ロックについて>
>>tp://www5f.biglobe.ne.jp/~f-lap/tips_adolock.htm
でも同じ動作になりした
別マシン側ででDT.MDBのProducts で 処理選択するか
レコード移動しなくてはいけない状況のように思われます
イメージ的には、
Function UpdateUnitsInStock
の動作の中で、編集中です とか 待機、ループで自動処理
できないものかと思っています
要領を得ない質問のような気がしますが、アドバイス頂けるとうれしいです
よろしくお願いいたします
Q3
MDB破損の話はよく見かけるのですが
今回のように、APP.MDB、DT.MDBを分離しても同じでしょうか
壊れる、運用可 のいろんな書き込みがあってよく理解できていません
実際にはどうなんでしょう?
アドバイスよろしくお願いいたします
(SQLサーバーについては、今後の目標にしています)
|
|