Access VBA質問箱 IV

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

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


1654 / 9994 ←次へ | 前へ→

【11631】Re:MDBの分離 と レコード操作
発言  pon  - 10/4/22(木) 16:13 -

引用なし
パスワード
   247b さん お手数かけます
わかり難い書込みのなか、回答ありがとうございます

10000文字超えのため、2度に分けました

>>DT.MDBがサーバー配置になるなら、確かにリンクテーブルの使用は微妙なラインです
詳細な説明ありがとうございます
勉強になります


Q1-1
添削頂きありがとうございます
サンプルコードが完全には理解出来ていないため
ldbが残りそうなところに
  Set rst = Nothing
  Set dbs = Nothing
を設けました

>レコードセットとデータベースを片付ける場合は、If not rst Is Nothing Then
>でオブジェクトが入っていることを確認した上で、Closeを呼び出した方が無難です。
了解です
上記
  If Not rst Is Nothing Then
    rst.Close
    Set rst = Nothing
  End If
  dbs.Close
  Set dbs = Nothing
に置き換えました

>ここに Resumeがあると、どんなエラーが発生しても実行再開してしまいますが、
>それで問題ないですか?
了解です
ありがとうございました


VBA の Recordset オブジェクトで共有データをロックする
tp://msdn.microsoft.com/ja-jp/library/cc376533.aspx

エラーのチェック
なんてありましたが、なかなか難しいです

>他者のロックで開けなかった場合、ここに来るはずなので、
>ユーザーに再度実行を促し、一旦処理終了する。
>何回かリトライする
>のいづれかの対処ができると思います。

これなんですが
下記コードに記載しましたが
    'ここは、
    'dbs Is Nothing の時 ・・・・では?
と思いますが・・・
 のでここには排他エラーが無いような気がしますが違っていますか?
(手動で開いて編集中、また、
別APP.MDBでSet DAOOpenTableExclusive = rst 中 共、どちらも同じで
   '↓ココでエラーで止まる!!
   Set rst = dbs.OpenRecordset(strRstSource, _
     dbOpenTable, dbDenyRead + dbDenyWrite)
となってしまいました
但し、どちらも先行命令が完了すれば、後攻命令も問題なく完了します)


>排他制御も最終的には、業務要件によってどれだけシビアなものが要求されるかが決まります。
勉強になります
ありがとうございます

>その意味では、現在作っている処理を様々なパターンでテストしてみてはいかがでしょうか。
この辺の対応どのようにして作りこむのか良くわかりません・・・難しいです・・
配布後、苦情の嵐とかに遭遇しそうな・・・・

DAOのロック系のエラーを調べてみたのですが
どのエラーが
>他者のロックで開けなかった場合、ここに来るはずなので、
となるのかわからなかったので

DAOのエラー定数一覧
tp://homepage2.nifty.com/Dee/vb/tips/daoerrorlist.html
(MSサイトでは見つけられませんでした)

エラー番号    エラーメッセージ
3006    データベース <データベース名> は排他ロックされています。
3008    テーブル <テーブル名> は排他ロックされています。
3009    テーブル <テーブル名> は現在使用されているため、ロックできませんでした。
3046    他のユーザーによってロックされているため、保存できませんでした。
3158    他のユーザーによってロックされているため、レコードは保存できませんでした。
3186    マシン <マシン名> のユーザー <ユーザー名> によってロックされているため、保存できませんでした。
3187    マシン <マシン名> のユーザー <ユーザー名> によってロックされているため、読み取れませんでした。
3188    このマシンの他のセッションによってロックされているため、更新できませんでした。
3189    テーブル <テーブル名> は、マシン <マシン名> のユーザー <ユーザー名> によって排他ロックされています。
3202    他のユーザーによってロックされているため、保存できませんでした。
3211    テーブル <テーブル名> は現在使用されているため、ロックできませんでした。
3212    テーブル <テーブル名> は、マシン <マシン名> のユーザー <ユーザー名> によって使用されているため、ロックできませんでした。
3218    ロックされているため、更新できませんでした。
3260    マシン <マシン名> のユーザー <ユーザー名> によってロックされているため、更新できませんでした。
3261    テーブル <テーブル名> は、マシン <マシン名> のユーザー <ユーザー名> によって排他ロックされています。
3262    テーブル <テーブル名> は、マシン <マシン名> のユーザー <ユーザー名> によって使用されているため、ロックできませんでした。

をエラー処理の対象にしてしまえばいいかなと組み込んでしまいました・・・
邪道みたいな気もするのですが・・・・
遭遇するエラーは何とか処理の記載は出来る気もするのですが・・・
未遭遇のもの、特に今回の場合??です
というわけでこんなハズカシコードになってしまいました (~_~;)
何かアドバイス有りましたらよろしくお願い致します

修正コード

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 
   'strRstSourceが開かれていると
   '実行時エラー '3262': テーブル 'DT02_PJ_DT' は、マシン 'K000040827' のユーザー 'Admin' によって使用されているので、ロックできませんでした。
   'で停止してしまう
   'DAOOpenTableExclusive2で、エラー処理組み込みテスト
   '↓ココでエラーで止まる!!
   Set rst = dbs.OpenRecordset(strRstSource, _
     dbOpenTable, dbDenyRead + dbDenyWrite)
   ' レコードセットが開いたことを確認します。開いた場合、
   ' Recordset オブジェクトを返します。開かなかった場合、Nothing を返します。
   If Not rst Is Nothing Then
     Set DAOOpenTableExclusive = rst  'レコードセット ロックで開いている
    
     '追加しないと ldb.MDBが残る
     '更新処理!!
    
     If Not rst Is Nothing Then
      rst.Close
      Set rst = Nothing
     End If
     dbs.Close
     Set dbs = Nothing    
     MsgBox "登録完了"
    
   Else   
     Set DAOOpenTableExclusive = Nothing    
     'ldbが残るとやなので、下記Nothingしています!!!!!    
     If Not rst Is Nothing Then
      rst.Close
      Set rst = Nothing
     End If
     dbs.Close
     Set dbs = Nothing    
   End If
  Else
 
    '他者のロックで開けなかった場合、ここに来るはずなので、
    'ユーザーに再度実行を促し、一旦処理終了する。
    '何回かリトライする
    'のいづれかの対処ができると思います。
 
          ’ここは、
          ’dbs Is Nothing の時 ・・・・
 
 
   'Set OpenTableExclusive = Nothing
    Set DAOOpenTableExclusive = Nothing    
    
     If Not rst Is Nothing Then
      rst.Close
      Set rst = Nothing
     End If
     dbs.Close
     Set dbs = Nothing
    
  End If
 
 
Exit Function
ErrorHandler:


  'If Err.Number = 3262 Then
  Select Case Err.Number
  
    Case 3006, 3008, 3009, 3046, 3158, 3186, 3187, 3188, 3189, 3202, 3211, 3212, 3218, 3260, 3261, 3262
  
      'MsgBox "エラーです"
      'MsgBox "ターゲットテーブルは排他ONで使用中です"
      'MsgBox Err.Description 'テーブル 'DT02_PJ_DT' は、マシン 'K000040827' のユーザー 'Admin' によって使用されているので、ロックできませんでした。
      '動作良好そう
      'ループかタイマで待機 駄目なら 時間を置いて と 思うが 動作的に 複数台のPCが ココでバッティングしたらどうなるのか自信がない
          
       '排他で開いていたら3回チャレンジして中止
       If cnt = 4 Then
      
        '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        'レコードセットとデータベースを片付ける場合は、If not rst Is Nothing Then
        'でオブジェクトが入っていることを確認した上で、Closeを呼び出した方が無難です。
        '----------------------------------------------------
      
        If Not rst Is Nothing Then
          rst.Close
          Set rst = Nothing
        End If
        dbs.Close
        Set dbs = Nothing
        
        MsgBox "ファイルが使用中か不具合が発生している可能性があります 時間を置いて登録できないときは管理者に連絡してください"
        
        
        Exit Function
        
       End If
      
       cnt = cnt + 1
      
      '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      'Resumeはここにあるべきでは?
      '----------------------------------------------------
      Resume
      
      '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      
    'Else
    Case Else
    
      MsgBox "エラー " & Err.Number & "" & Err.Description & " が発生しました"
      
       If Not rst Is Nothing Then
        rst.Close
        Set rst = Nothing
       End If
       dbs.Close
       Set dbs = Nothing
      
      Exit Function
            
  'End If
  End Select
 
  '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


今回は、取合えずテーブルロックで大丈夫そうな気がするのと
レコードレベルでの操作は荷が過ぎそうなので
テーブルロックで進めてみようと思います

6,248 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 発言[未読]

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