Access VBA質問箱 IV

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

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


434 / 2272 ツリー ←次へ | 前へ→

【11717】LANでのWithEventsは無謀ですか pon 10/7/9(金) 10:46 質問[未読]
【11719】Re:LANでのWithEventsは無謀ですか 247b 10/7/9(金) 13:47 発言[未読]
【11722】Re:LANでのWithEventsは無謀ですか pon 10/7/9(金) 18:36 発言[未読]
【11723】Re:LANでのWithEventsは無謀ですか 247b 10/7/11(日) 15:13 発言[未読]
【11724】Re:LANでのWithEventsは無謀ですか pon 10/7/12(月) 19:20 発言[未読]
【11727】Re:LANでのWithEventsは無謀ですか 247b 10/7/13(火) 14:10 発言[未読]
【11728】Re:LANでのWithEventsは無謀ですか 247b 10/7/13(火) 14:41 発言[未読]

【11717】LANでのWithEventsは無謀ですか
質問  pon  - 10/7/9(金) 10:46 -

引用なし
パスワード
   こんにちは よろしくお願いいたします


都港区会社A-同じ建物 同一部署 3人
都多摩会社B 1人
で下記、試しましたが、多摩の人だけがうまく動作しません

下記のような使用可能なのでしょうか
可能、不可能等
アドバイス頂けると助かります
よろしくお願いいたします


動作概要

・ファイルサーバーに帳票(エクセルブック)を保存しています
・アクセスDT.mdbに上記一覧リストのテーブルを有しています
・アクセスFRM.mdb(配布用、ローカルPCで使用)は
  DT.mdbの一覧リストをデータシート形式で表示
  レコード選択で、ファイルサーバの帳票ブックを開く(同時使用は禁止) 
  アクセスのクラスモジュールのWithEventsで
    セル編集時、指定セル値取得
    帳票ブック保存時、DT.mdbのレコード更新

 としていますが、多摩の人だけ、DT.mdbへの更新が出来ていません

 クラスモジュール WithEvents の 理解足りていないため
 デバッグもいまいち思い通りに出来ていないです

 何かアドバイス頂けると助かります
 よろしくお願いいたします
 

'----------------------------------------------------------------
アクセスコード
'----------------------------------------------------------------
Class1

Private Sub xlsApp_WorkbookBeforeSave(ByVal Wb As Excel.Workbook, ByVal SaveAsUI As Boolean, Cancel As Boolean)

  'tmpテーブルdt登録
  edit_TmpT_PJ_DT  
  
  'SVテーブルdt登録
  edit_DT02_PJ_DT  
  
End Sub

'----------------------------------------------------------------
Module10

'ローカルPC内TMPテーブルにレコード追加
Function edit_TmpT_PJ_DT()
   Dim db As Database
   Dim RT As Recordset
   Set db = CurrentDb
  
   db.Execute ("DELETE FROM TmpT_PJ_DT")  
  
   Set RT = db.OpenRecordset("TmpT_PJ_DT", dbOpenTable)
  
   On Error Resume Next
   RT.MoveFirst

   'RT.Edit
   RT.AddNew
  
    RT![依頼部署] = da1_iraibusyo
    ・
    ・
    RT![IDX] = d0_NO
    
   RT.Update
  
   On Error GoTo 0

   RT.Close
   db.Close
End Function

'サーバー更新
'Function edit_DT02_PJ_DT()
Sub edit_DT02_PJ_DT()

  Dim ws As DAO.Workspace
  Dim db As DAO.Database
  Dim rs As DAO.Recordset
  Dim strSQL As String
  Dim I As Long
  
  strSQL = "SELECT DT02_PJ_DT.*, DT02_PJ_DT.IDX FROM DT02_PJ_DT IN '" & LC_get_path & "' WHERE DT02_PJ_DT.IDX=""" & Forms("MF01_JOB選択F").Controls("T02_PJ_DT").Controls("IDX") & """;"
  
  Set ws = DBEngine.Workspaces(0)
  Set db = CurrentDb
  Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)
  ws.BeginTrans
  
  rs.Edit

    rs![依頼部署] = da1_iraibusyo
    ・
    ・
    rs![mckd] = d32_mckd_dt
  
  rs.Update
  
  ws.CommitTrans
  rs.Close
  Set rs = Nothing
  db.Close
  Set db = Nothing
  
End Sub

'----------------------------------------------------------------

【11719】Re:LANでのWithEventsは無謀ですか
発言  247b  - 10/7/9(金) 13:47 -

引用なし
パスワード
   こんにちわ

▼pon さん:

>で下記、試しましたが、多摩の人だけがうまく動作しません
LANであっても、距離があるので、回線の細さが影響している可能性もあり得ます。
その場合は、多摩から更新をかけてしばらく放置しておけば更新されているという動きをするはずです。原因としては可能性は低いですが、念のため。


>Private Sub xlsApp_WorkbookBeforeSave(ByVal Wb As Excel.Workbook, ByVal SaveAsUI As Boolean, Cancel As Boolean)
ブレークポイントを仕掛けるとしたら、↑の行に置けば、エクセルの保存処理直前にこの行で止まるはずです。

>  strSQL = "SELECT DT02_PJ_DT.*, DT02_PJ_DT.IDX FROM DT02_PJ_DT IN '" & LC_get_path & "' WHERE DT02_PJ_DT.IDX=""" & Forms("MF01_JOB選択F").Controls("T02_PJ_DT").Controls("IDX") & """;"

このSQL文、DT02_PJ_DT.IDXをSELECTしてますが、不要ではないかと思います。
それがなければ、dbOpenDynasetではなく、dbOpenTableでRecordsetを開けると思うのですが。
個人的にですが、ダイナセットは追加・更新・削除では使用しないようにしています。

あと、
LC_get_path変数には、ネットワークパス(\\サーバー名\フォルダ名\フォルダ名 という形式)が入っているのでしょうか。その場合、ドライブレターを割り当てる(X:\フォルダ名\フォルダ名 などの形式)に変更した方が無難に思います。IN句でネットワークパスを使用すると、環境によってはうなく参照できない場合があるようです。
その意味では、多摩環境のネットワーク設定が、他と同じになっているかを確認してみるのも良いと思います。

とはいえ、まずはデバッグしてみるのが良いかと。
イベントプロシージャは、例えばボタンをクリックした時の処理を記述するものですが、WithEvents指定した変数のオブジェクトについても、同様にそのオブジェクトでイベントが発生した場合、そのイベント発生時の処理を記述できるようにするものです。
このため、
Private Sub xlsApp_WorkbookBeforeSave(ByVal Wb As Excel.Workbook, ByVal SaveAsUI As Boolean, Cancel As Boolean)
という記述は、ボタンのクリックイベントと同じ用な感覚で、xlsApp変数に格納されているExcel.ApplicationオブジェクトのWorkbookBeforeSaveイベント発生時の処理を記述していることになります。
コードと説明を拝見する限り、WithEventsはExcelのオブジェクトに対して定義しているようなので、LANとの関係は特にないと思われます。
純粋にLAN環境でのDAOの使用に関わる問題ではないでしょうか。
うまく説明できているかわかりませんが。

【11722】Re:LANでのWithEventsは無謀ですか
発言  pon  - 10/7/9(金) 18:36 -

引用なし
パスワード
   247b さん ありがとうございます

>LANであっても、距離があるので、回線の細さが影響している可能性もあり得ます。
>その場合は、多摩から更新をかけてしばらく放置しておけば更新されているという動きをするはずです。
ん〜 そうなんですか
この辺の知識皆無です 勉強になります


>このSQL文、DT02_PJ_DT.IDXをSELECTしてますが、不要ではないかと思います。
>それがなければ、dbOpenDynasetではなく、dbOpenTableでRecordsetを開けると思うのですが。
>個人的にですが、ダイナセットは追加・更新・削除では使用しないようにしています。

うう この辺の知識も整理されていません
実際のところ色々な書き方があって理解しないままそのとき目に付いたものを使用みたいなです


>このSQL文、DT02_PJ_DT.IDXをSELECTしてますが、不要ではないかと思います。

FROM DT02_PJ_DT INNER JOIN TmpT_PJ_DT ON DT02_PJ_DT.IDX = TmpT_PJ_DT.IDX
みたいにしとけばよい であっていますか?


>それがなければ、dbOpenDynasetではなく、dbOpenTableでRecordsetを開けると思うのですが。

こちらもいまいち理解が乏しく、ググッてみました

OpenRecordset メソッドのレコードセット
 ://www.tsware.jp/labo/labo_04.htm
では Table が早い との記述がありました

また

dbOpenTable と dbOpenDynaset の違い
 ://uwasora.at.webry.info/200907/article_7.html
では
OpenrecordsetのType(開く種類)
 ://web.archive.org/web/20051031204518 ://www.penhagi.com/access/ota2001/5941.htm
の紹介がありましたが
ずいぶん前のQAでした
この人はどうやって拾ったんだろう??

その他、アドバイスありましたらよろしくお願いいたします


>ドライブレターを割り当てる(X:\フォルダ名\フォルダ名 などの形式)に変更した方が無難に思います。>IN句でネットワークパスを使用すると、環境によってはうなく参照できない場合があるようです。
時折他作業で、フルパス直書き時、いつまでたっても接続できないこともありました
なるほどです ありがとうございます


>とはいえ、まずはデバッグしてみるのが良いかと。
多摩では、VBA触れる人がいないので、出力するものを送って試してみようと思います

>純粋にLAN環境でのDAOの使用に関わる問題ではないでしょうか。
ありがとうございます
可能なことがわかって安心できました

月曜以降になってしまいますが、アドバイス頂いた事項試してみたいと思います

【11723】Re:LANでのWithEventsは無謀ですか
発言  247b  - 10/7/11(日) 15:13 -

引用なし
パスワード
   こんにちわ
とりあえず、下記だけ。

>>このSQL文、DT02_PJ_DT.IDXをSELECTしてますが、不要ではないかと思います。
>は
>FROM DT02_PJ_DT INNER JOIN TmpT_PJ_DT ON DT02_PJ_DT.IDX = TmpT_PJ_DT.IDX
>みたいにしとけばよい であっていますか?

strSQL = "SELECT DT02_PJ_DT.*, DT02_PJ_DT.IDX FROM DT02_PJ_DT IN '" & LC_get_path & "' WHERE DT02_PJ_DT.IDX=""" & Forms("MF01_JOB選択F").Controls("T02_PJ_DT").Controls("IDX") & """;"

というSQLなので、TmpT_PJ_DTは使用してないと思うのですが。

【11724】Re:LANでのWithEventsは無謀ですか
発言  pon  - 10/7/12(月) 19:20 -

引用なし
パスワード
   ▼247b さん: ありがとうございます
途中報告です テストは明日以降となってしまいました


>>ドライブレターを割り当てる(X:\フォルダ名\フォルダ名 などの形式)に変更した方が無難に思います。
>>IN句でネットワークパスを使用すると、環境によってはうなく参照できない場合があるようです。
>時折他作業で、フルパス直書き時、いつまでたっても接続できないこともありました
>なるほどです ありがとうございます

ドライブレターの割り当てを組み込んでみましたが
割り当て先を触られることがありそうな気がして悩んでしまいました
結局、
起動時割当、終了時割当削除
起動時既割当なら、割当済みでした 管理者に報告する メッセージ で終了
みたいな感じにしました
普通はどのような処理になるのでしょうか
上記、まだ多摩では試していませんがコメント有ればよろしくお願いいたします


>とりあえず、下記だけ。

>というSQLなので、TmpT_PJ_DTは使用してないと思うのですが。
ありがとうございます
SQL確認しました
ユーザーフォームのアクティブレコードが対象になるということですね

動作的には
1、サブフォームのレコードWクリックでファイルサーバーの対象のブックを開く
2、ブックが編集されたら、frm.mdbのtmpテーブルにdt書き込み(1レコードしか存在しない)
3.ブック保存時に、上記テーブルのレコードでdt.mdbのレコードを更新する
通常であれば
DT.mdbの更新先レコードは、サブフォームのアクティブレコードで指定出来ると思いますが
使用者がどんな操作をするのかわからず、途中でmdbをみた拍子にアクティブレコードが
変わってしまうかも知れない
保存時イベントで、更新するレコードはtmpテーブルのレコードを元にするので間違いはない
また
同一形式のテーブルに保存できているので、更新操作時予定外の不具合が発生することはない
といった思いでした

もともとこの辺、勝手な理解しかしていないのですが
TmpT_PJ_DTを元に更新処理を進めるのは不利な操作となるのでしょか

動作確認は
クエリのデータシートビューで確認して安心しているみたいな状況なので・・・

コメント有りましたらよろしくお願いいたします

【11727】Re:LANでのWithEventsは無謀ですか
発言  247b  - 10/7/13(火) 14:10 -

引用なし
パスワード
   こんにちわ
>ドライブレターの割り当てを組み込んでみましたが
>割り当て先を触られることがありそうな気がして悩んでしまいました
>結局、
>起動時割当、終了時割当削除
>起動時既割当なら、割当済みでした 管理者に報告する メッセージ で終了
>みたいな感じにしました
>普通はどのような処理になるのでしょうか
>上記、まだ多摩では試していませんがコメント有ればよろしくお願いいたします

たしかに、上記のような配慮は必要ですね。以前、似たようなロジックをみたことがありますが、
そのときは、割当済みかどうかのチェックをせずに問答無用で起動時割当というロジックでした。
それでも動くんですが、ちょっと怖いので、割当済みのチェックが可能なら組み込んだ方が個人的には良いかと思います。その分、ロジックは複雑になりますが。


>TmpT_PJ_DTを元に更新処理を進めるのは不利な操作となるのでしょか
一旦、Tmpテーブルに保持してその後、本体へ更新をかけるという処理自体は、良く用いられる手段なので問題ないと思います。
問題になりうるとしたら、以前の投稿でもあったように、排他制御の方ですね。
そう言えば、今になって思い出したのですが、更新方法にも、2つの方法があります。と言っても、個人的にそう言ってるだけですが。
UPDATE方式:ponさんが現状行っている方式
DELETE&INSERT方式:UPDATEは使用せず、元のデータを一旦、削除し、改めてINSERTする。
 元のデータが無くてもDELETEは通るので、新規追加に関して考慮する必要がないメリットがあります。
 ただ、この方式では、ファントム・リードという問題が発生しうるため、実際には、
 元のデータの存在チェック→無かったら待機後再実行、または再実行をユーザーに指示して終了
 ↓
 有ったら、DELETE
 ↓
 INSERT
 という手順を取るべきです。プログラムは複雑になりますが、データ自体で排他がかけられるので、私の周囲では良く用いられていました。いまさら思い出してすみません。

【11728】Re:LANでのWithEventsは無謀ですか
発言  247b  - 10/7/13(火) 14:41 -

引用なし
パスワード
   不足があったので追記です。

ローカルでのデータ存在チェック。新規か更新かを判断する。(画面の表示データや、内部で保持しているデータから。tempテーブルにフラグを立てるという方策も有り)
新規の場合
↓ 更新の場合
↓ ↓
↓ 元のデータの存在チェック→無かったら待機後再実行OR再実行をユーザーに指示して終了
↓ ↓
DELETE
↓ ↓
INSERT

念のためですが、厳密には排他制御ではありません。
非常にシビアな更新(多くのユーザーが同じデータに更新をかける可能性が高いような場合)
には、この方式ではデータを保証できない可能性があります。その場合、排他制御が必要です。

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