Access VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


1658 / 9994 ←次へ | 前へ→

【11627】Re:MDBの分離 と レコード操作
質問  pon  - 10/4/21(水) 18:27 -

引用なし
パスワード
   遅くなりました
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サーバーについては、今後の目標にしています)
4,755 hits

【11601】MDBの分離 と レコード操作 pon 10/4/9(金) 15:26 質問[未読]
【11602】Re:MDBの分離 と レコード操作 pon 10/4/9(金) 15:40 発言[未読]
【11603】Re:MDBの分離 と レコード操作 247b 10/4/12(月) 10:16 発言[未読]
【11604】Re:MDBの分離 と レコード操作 pon 10/4/12(月) 18:16 質問[未読]
【11605】Re:MDBの分離 と レコード操作 247b 10/4/12(月) 23:07 発言[未読]
【11606】Re:MDBの分離 と レコード操作 pon 10/4/14(水) 18:37 質問[未読]
【11607】Re:MDBの分離 と レコード操作 247b 10/4/14(水) 19:26 発言[未読]
【11608】Re:MDBの分離 と レコード操作 pon 10/4/15(木) 14:27 発言[未読]
【11609】Re:MDBの分離 と レコード操作 247b 10/4/15(木) 17:10 発言[未読]
【11627】Re:MDBの分離 と レコード操作 pon 10/4/21(水) 18:27 質問[未読]
【11628】Re:MDBの分離 と レコード操作 247b 10/4/22(木) 4:44 発言[未読]
【11631】Re:MDBの分離 と レコード操作 pon 10/4/22(木) 16:13 発言[未読]
【11638】Re:MDBの分離 と レコード操作 247b 10/4/23(金) 20:18 発言[未読]
【11632】Re:MDBの分離 と レコード操作 pon 10/4/22(木) 16:13 発言[未読]

1658 / 9994 ←次へ | 前へ→
ページ:  ┃  記事番号:
1078196
(SS)C-BOARD v3.8 is Free