過去の桐井戸端BBS (桐ver.8)
3837 他ユーザーが使用中のファイルが更新中であるか調べたい su 1999/12/19-19:18
いつも勉強させていただいています。
現在v8SP3を使用していますが、ネットワークにおける質問をさせていただきます。
授業.tblの併合を行いたいのですが、他ユーザーが授業.tblを更新中であれば行わず、
そうでなければ、併合させるイベントを発生させたいと思うのですが、#表オープン状態( n | file , f ) 、
#編集状態( n ) 、#ファイル使用( str , f )、#ロック行数 などを使ってみましたが、どうもうまくいきませんでした。
式の立て方に問題があるのかもしれませんがよろしくお願いいたします。
ちなみにフォーム開始イベントに下記のように書き込んであります。

   表 "授業",モード=共有更新
   併合 "作業 授業日付.tbl",置換,{[授業ID]照合[授業ID],[日付2]複写
[日付2]}
   終了 表 *

3842 Re:他ユーザーが使用中のファイルが更新中であるか調べたい 佐田 守弘 1999/12/19-21:28
記事番号3837へのコメント
suさん
ネットワーク上で共有更新で使っている時には、表を開いただけで更新状態になります。
仮にバックアップありの設定がされてあっても、この設定は無視され、バックアップなしの
設定の時と同じ扱いになります。
従いまして、他のユーザーが更新かどうかを調べる事には意味がありません。
調べるなら、同じファイルを共有更新で開いている他のユーザーがいるかどうかを調べるだ
けです。

あるいは、ご質問の更新状態とは、項目値の文字列を編集している時(行訂正のモード)とい
う意味でしょうか。だとしたら、おそらく調べられないのでは。

佐田守弘(KS-00119)

3846 Re:他ユーザーが使用中のファイルが更新中であるか調べたい su 1999/12/20-02:21
記事番号3842へのコメント
佐田先生、早速のご回答ありがとうございます。
>あるいは、ご質問の更新状態とは、項目値の文字列を編集している時(行訂正のモード)とい
>う意味でしょうか。だとしたら、おそらく調べられないのでは。

その通りです。これを調べる関数はないのですか。残念です。

>調べるなら、同じファイルを共有更新で開いている他のユーザーがいるかどうかを調べるだ
>けです。

どの関数を使ったら調べられるのでしょうか。出来るだけ具体的にご回答いただけるとありがたいの
ですが。よろしくお願いいたします。

3849 Re:他ユーザーが使用中のファイルが更新中であるか調べたい Rockey 1999/12/20-12:15
記事番号3846へのコメント
>どの関数を使ったら調べられるのでしょうか。出来るだけ具体的にご回答いただけるとありがたいの
>ですが。よろしくお願いいたします。

割り込みしてすいません。

loop
if (#ファイル使用(&授業TBL,1)=1) /*更新モードで開けたら
表 &授業TBL,表番号=10,モード=共有更新 /*以下の処理をする
併合 "作業.tbl",両方,{*************}
終了 表 10
break /*繰り返しループをぬける
else
確認 "他ユーザー使用中" /*確認メッセージをだして
break /*繰り返しループをぬける
end
end

更新モードで開けたら併合を実行するという考え方です。
elseの部分をとれば他ユーザーが閉じるまで繰り返し待ちます。
一括処理の抜粋ですが、イベントでもいけるはずです。

先生と察しますが、難しいことをされてますね
また、夜遅くの投稿お疲れ様です。
おたがいにがんばりましょう。

3855 Re:他ユーザーが使用中のファイルが更新中であるか調べたい su 1999/12/20-16:53
記事番号3849へのコメント
Rockeyさんコメントありがとうございます。
さっそく試してみましたところ、(#ファイル使用(&授業TBL,1)=1は更新を許可しているファイルであるかどうか調
べるようです。ですから、他ユーザーがレコード訂正中であっても、レコードロックがかかるだけで、ファイルは
更新で開けてしまいます。そのまま併合に進と、「KD1450:他のユーザが処理中です」が帰ってきてしまいました。
どうも無理なのでしょうかね。
もう少し考えてみます。

3866 Re:他ユーザーが使用中のファイルが更新中であるか調べたい Rockey 1999/12/20-23:28
記事番号3855へのコメント
失礼しました。
共有更新で開かれていると、開いてしまいますね
それでは

roop
if (#表オープン状態(&授業TBL,1)="")
表 &授業TBL,表番号=4,モード=共有更新
併合 1,両方,{*********}
終了 表 4
break
else
確認 "他ユーザーが使用中"
break
end
end

これだと、共有でも専有でも誰かが開いていたらだめです。

あと、会話処理を禁止する前提だと共有更新で開いたら
変数に値を代入しチェックする手もありますね

3868 Re:他ユーザーが使用中のファイルが更新中であるか調べたい 佐田 守弘 1999/12/21-00:19
記事番号3846へのコメント
suさん
最初の質問の主旨に戻って考えてみます。
主旨は、マスタファイルに対して併合処理を行うので、その間に他のユーザが更新モードで開いていないかを
調べ、更新していない時に併合を行いたいという事だったと思います。そして、前のコメントでも書きました
様に、共有更新状態で複数ユーザーが表を開いていれば、編集を行っているかどうかにかかわらず、表の更新
状態であり、併合の様な操作はできないわけです。

併合処理中はファイルロック状態になります。ですから、もし他のユーザーが更新中であると、併合処理が行
えません。このため、他のユーザーの更新を止めさせるか、他のユーザーが表を開いていない時に行う必要が
あります。

そして、他のユーザーがその表を開いているかどうか、更新中であるかを調べる関数はなさそうです。
対応策として、

@表を専有モードで開く
表を専有モードで開けば、他のユーザーはその表を更新モードでは開けなくなります。つまり併合の様な処理
を行うには、専有モードで開くのが1つの方法です。
コマンドは、
表 <表ファイル名>,表番号=<整数>,モード=専有,リトライ=する|しない,終了状態=&結果
ですが、
「モード=専有」は省略できます。
「リトライ」は、「しない」にして、開けなかったらエラーを返させるのが1つの方法です。
「終了状態=」には、専有モードで開けたかどうかの結果が戻されます。
1 表を開いた。
0 共有違反以外のエラーが発生したため、表を開くことができなかった。
-1 共有違反で表を開くことができない(「リトライ=しない」を指定した場合のみ)。
-2 他の利用者が置換や併合などの処理を実行中(ファイル排他)。
この結果を使ってケースコマンドで併合を行うか、メッセージを表示して待つ事にするか、あるいは繰り返し
コマンドで開けるまで何回もループさせるかなど、やり方はいろいろあると思います。

Aトランザクションコマンドを使う
トランザクションコマンドを使うと、一連の手順を終了するまで、他のユーザーの更新を排除できる様です。
つまり、

トランザクション 開始
併合 ・・・・,終了状態=&結果
ケース開始
 ケース (&結果=1)
トランザクション コミット
メッセージボックス "併合結果","併合終了",アイコン=i,ボタン指定=1
 ケース その他
  トランザクション ロールバック
メッセージボックス "併合結果","併合はできませんでした",アイコン=E,ボタン指定=1
ケース終了

の様な形で使うのだと思います。

佐田守弘(KS-00119)

3869 Re:他ユーザーが使用中のファイルが更新中であるか調べたい hidetake 1999/12/21-01:12
記事番号3868へのコメント
>そして、他のユーザーがその表を開いているかどうか、更新中であるかを調べる関数はなさそうです。

こう言った処理は桐の場合「専有モード」で行う方が良いとは思いますが、 最悪、#ロック可能行数
が 814 であったら、更新されていないと見なすのはどうでしょう?何かありましたっけ?

しかし、K3 は共有をどのように考えているのか良くわかりませんね!
前に共有状態での「読み取り一貫性」(参照同一性)の問題を問い合わせた場合は思わぬ答えが返って
きた事があります。
ノートパソコンとか他のパソコンを1台用意してください。マスターと実際に使うファイルは別にし、
マスターはクライアントからは参照せず、別に複写した参照用のファイルを使用してください。更新
があったレコードは「その1行」をファイルとして書き出します。ノートパソコンで常時ループして
おき、ファイルが書き出されたのを監視して更新が掛かったら、それをマスターに反映して下さい。
マスターを常時使う参照ファイルと更新するのはタイミングを見て更新する必要があります...
要は、銀行のオンラインシステムと同じようなバッチ処理を行えと言うのですね!
それもここまで話を持っていくのに、制御系ではとか... パケットレベルでの遅延とか... その話の
レベルの凄いこと凄いこと...
しかし、まともな DB で「読み取り一貫性」を確保するのにそのような処理まで行う必然性を見た事
がありません...

桐ではそのような面倒な処理を行うか、すべての参照ファイルを専有モードで開かない限り、完全な
整合性を保ったデータの更新や参照は行えない可能性があります。

少々内容がズレてしまいました。


3871 Re:他ユーザーが使用中のファイルが更新中であるか調べたい hidetake 1999/12/21-02:24
記事番号3869へのコメント
>こう言った処理は桐の場合「専有モード」で行う方が良いとは思いますが、 最悪、#ロック可能行数
>が 814 であったら、更新されていないと見なすのはどうでしょう?何かありましたっけ?

これは相手が訂正や追加を行っているときは正しくロック可能な行数を返すみたいですが、置換や
併合を行っているときは、画面上では鍵マークが表示されているにも関わらず、全くロック可能な
行数を返さず 814 となるようです。実際にはロックできないのに...
従って、他のチェックも必要なようですネ。

それと、#ファイル使用()も自分自身が開いた表が表引きで参照しているだけで、実際にはリード
ライトできるにも関わらず、できないと返してくるというとんでもない仕様なので、結局は実際に
その処理を行ってみてできるかできないかをチェックした方が良い場合もあります。

他には「フォカース設定検査」なんてメソッドも、ファイルオープン時、SP2 では使えたものが
SP3 では使えなくなったものの、実際には「フォーカス設定」は行えるので、検査せずにやって
しまえというのもあります。 (;_;)


3878 Re:他ユーザーが使用中のファイルが更新中であるか調べたい su 1999/12/21-11:03
記事番号3866へのコメント
私もこれは試してみたのですがうまくいきませんでした。
と言いますのは自分自身がファイルを共有で開いている場合は1を返してくるよう
ですが、他のユーザーが開いている場合には効果がないようです。
???????????????????
と言う状態です。

3881 出来ました。ありがとうございます。 su 1999/12/21-11:45
記事番号3868へのコメント
佐田先生いつも詳しいご回答に感謝しています。

> 表 <表ファイル名>,表番号=<整数>,モード=専有,リトライ=する|しない,終了状態=&結果

終了状態で判断させるのには気が付きませんでした。つい、関数ばかりに目を奪われていたようです。
(でも、このような関数があっても良いような気がしますが。)
そこで、ご指示のように組んでみましたら、成功いたしました。ありがとうございます。
トランザクションを使えば、共有のまま行えそうですが、どうもうまく動いてくれませんでした。
おいおい勉強しながら完成させていこうと思います。
これからもよろしくお願いいたします。
それと、桐ガイドブック、待ち遠しいですね。がんばってください。

戻る