開いているTIBQueryがEDatabaseErrorとなる原因は?

解決


ティモテ  2014-07-24 00:31:08  No: 46480

Form1で受付ボタンを押すとそのフォームで表示されているIDの人をデータモジュールで定義されている待ちリストに追加するという処理があります。
追加する際に色々なif文で登録するデータが正しいかどうかをチェックしていて、そのチェックの一つにShowMessageDlgを使用して「はい」or「いいえ」を押す処理があるのですが、これを押した時に同じIDで同じif文の通り方をしているのに開いているTIBQueryがEDatabaseErrorとなってしまうことがあります。
何が原因と考えられるでしょうか、具体的には以下の通りです。

TForm1で受付ボタンを押すと
>DM4.AppendWaitList(nedCode.AsInteger, DM4.InputDate);  //nedCode=対象ID,InputDate=受付時の時間
が走ります。

AppendWaitListはデータモジュールのDataMod4.pasで定義されており、内容としては
1.引数のIDをibquePersonDataのParamに入れ、その値を元にibquePersonData:TIBQuery  を開く(ibquePersonData.Open)
2.ibquePersonDataの様々なFieldの値を定数と比較し、if文から外れたらbError:BooleanをTrueにする
3.bError=FalseならibcdsWaitList:TIBClientDataSetにデータを追加する
を行っています。
デバッグ実行をする際、ibquePersonDataのSQL文でselectしている一つのフィールドを
ibquePersonData.FieldByName('SYUBETU').AsInteger…①
を監視してデバッグ実行を行うと
1.の時点で①=1と値が入っています。
2.の段階でも値は入ったままですが
>if ShowMessageDlg('項目1を確認してください。'#13'入力を続けますか?', mtConfirmation) <> mrYes th>en
  bError := True;
このif文でメッセージダイアログを表示させ、「はい」「いいえ」どちらかをクリックした時、監視式の値が
Delphiの例外:EDatabaseError($3BCF91D) //()内の値は毎回変わっています
となることがあります。(他のibquePersonData.FieldByName('その他色々')も同様に読み取れなくなっています。)
その数行後に
>if ibquePersonData.FieldByName('SYUBETU').AsInteger = 2 then
と比較している部分があるためここで
'ibquePersonData:項目'SYUBETU'が見つかりません'
とエラーになってしまいます。


igy  2014-07-24 00:59:07  No: 46481

>if ShowMessageDlg('項目1を確認してください。'#13'入力を続けますか?', mtConfirmation) <> mrYes then

>if ibquePersonData.FieldByName('SYUBETU').AsInteger = 2 then
の間で、ibquePersonDataに対して、何か操作されてますか?

また、
>監視してデバッグ実行を行うと
とありますが、監視せずに、通常の実行でも、同様のエラーは表示しますか?


ティモテ  2014-07-24 01:21:14  No: 46482

>igyさん
上部についてですが、間にif文が一つありますが、このデータでは通らないので何も操作していません。

下部についてですがデバッグではなくexeを起動して同じ操作を行っても
>>if ibquePersonData.FieldByName('SYUBETU').AsInteger = 2 then
>と比較している部分があるためここで
>'ibquePersonData:項目'SYUBETU'が見つかりません'
とエラーとなることがあります。

また色々触っていたのですが、どうも受付ボタンを押してから6秒ほど待って「はい」or「いいえ」を押すと確実にこのエラーになるようです。
最速で押すと必ずエラーが出ないかというとそういうわけでもなく、受付がF11で行えるのでF11を押しっぱなしにして、「いいえ」ボタンが出る場所の上にカーソルを置いて左クリックを連打すると10〜30回ほど押す間に1回はエラーが出ます。


igy  2014-07-24 01:32:22  No: 46483

では、

>どうも受付ボタンを押してから6秒ほど待って「はい」or「いいえ」を押すと確実にこのエラーになるようです。

この6秒+「はい」or「いいえ」選択のあいだに、別のイベントとかで、ibquePersonDataに対して、何か操作が発生したり
する可能性は、ありませんか?


ティモテ  2014-07-24 02:13:47  No: 46484

>igyさん
無い…と思います、少なくともデバッグしていて別のイベントは走りません。
また、間にあるif文では基本的にFieldByNameの値と定数を比較して違ったらbError=Trueにしているだけで、ibquePersonDataの方に代入したりする式はありませんでした。
また、EDatabaseErrorとなるときもならないときもデバッグ上で通る箇所は全く同じです。
AppendWaitListの動作をもう少し細かく書くと以下の通りです。

TDM4.AppendWaitList(iCode: Integer; dtDate: TDateTime;
  bCheck: Boolean): Boolean;

 ibquePersonData.ParamByName('KJCD').AsInteger := iCode;
 ibquePersonData.ParamByName('HKHENKOUBI').AsDateTime := dtDate;
 ibqueKanjaData.Open; //この行を実行すると監視している値=1と表示されます

ここからif文が並んでいます

 if (70歳以上で項目1=50なら) then
 begin
  if ShowMessageDlg('項目1を確認してください。'#13'入力を続けますか?', mtConfirmation) <> mrYes then
  //上の行を実行するまでは監視式=1のままでが、実行すると監視式=EDatabaseErrorとなることがあります。
   bError := True;
 end;

if not bError then
    begin
      ibcdsWaitList.Append;

というような処理を行っています。

そんなに複雑なプログラムではないのですが、デバッグで追っている時にデバッグで通らないがibquePersonDataをいじっているということはあるのでしょうか?


igy  2014-07-24 02:26:45  No: 46485

> ibqueKanjaData.Open; //この行を実行すると監視している値=1と表示されます

ibquePersonData.Open;

ではなくて?


ティモテ  2014-07-24 02:30:02  No: 46486

失礼しました
ibquePersonData.Open;
です。


igy  2014-07-24 02:36:53  No: 46487

では、
'ibquePersonData:項目'SYUBETU'が見つかりません'のエラーが出たときの
ibquePersonData.SQLと、Openを実行する前のibquePersonData.SQLを比較してみるとどうなりますか?


ティモテ  2014-07-24 18:45:46  No: 46488

ibquePersonData.SQL.SaveToFile('SQL*.txt');

ibqueKanjaData.Open;
if ShowMessageDlg('項目1を確認してください。'#13'入力を続けますか?', mtConfirmation) <> mrYes then
finally文の中(ibquePersonData:項目'SYUBETU'が見つかりません'のエラーが出たときのSQL)
の各行の前後に配置して保存ファイルの比較を行いましたが、
正常に進むとき、ibquePersonDataがEDatabaseErrorとなるときの両方で、保存したSQLは全て同じでした。


ティモテ  2014-07-24 18:53:58  No: 46489

すみませんまた
ibqueKanjaData.Open;
となっていますが正しくは
ibquePersonData.Open;
です。


ティモテ  2014-07-24 19:03:23  No: 46490

デバッグ時の監視式
ibquePersonData.FieldByName('SYUBETU').AsInteger…①
を見ていると
>if ShowMessageDlg('保険負担率を確認してください。'#13'入力を続けますか?', mtConfirmation) <> mrYes then
の行実行前までは必ず正常な値を監視できています。
この行を実行し、ダイアログが出ている間(はいorいいえをクリックする前)は必ず[監視できません]となります。
この後はいorいいえをクリックすると
・正常な値を監視できている状態
・監視式の値が「Delphiの例外:EDatabaseError($*F91D)
のどちらかの状態となります。


au  2014-07-24 19:45:41  No: 46491

ShowMessageDlgて標準の関数じゃないと思うんですけど、その中で何かやってるんじゃないでしょうか?


ティモテ  2014-07-24 22:26:19  No: 46492

>auさん
ShowMessageDlgの中身を追った所原因が分かりました。
呼び出し元のTForm1にタイマー処理があり、タイマーイベントでトランザクションをコミットしている処理があり、その後ibquePersonData.OpenをしていないためEDatabaseErrorとなってしました。
ダイアログをFormshowで表示した時にTForm1のタイマーの処理が動作していました。

TForm1で受付ボタンを押した時にTimerのIntervalを0にして、戻ってきたら元の値に戻せば対応できそうなのでそのような処理を追加してみます。

igyさん、auさん大変助かりました。
ありがとうございます。


ティモテ  2014-07-25 02:32:49  No: 46493

解決です。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加