• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:オブジェクトの処理を途中でキャンセルさせたい)

オブジェクトの処理を途中でキャンセルさせたい

このQ&Aのポイント
  • WindowsXP(SP2)とVisual Basic6.0(SP6)を使用して開発中です。A.exeとB.dllがあり、B.dllの処理中にA.exeでキャンセルボタンを押した場合に中断させたいです。
  • A.exeからclsMain、clsMainからfrmMainへキャンセルボタンの通知はできますが、clsMainからclsSubへの通知方法がわかりません。
  • clsSubの処理は長時間かかるため、中断できる仕組みを作りたいです。

質問者が選んだベストアンサー

  • ベストアンサー
  • ape5
  • ベストアンサー率57% (85/148)
回答No.4

そこまで考えてませんでした^^; 標準モジュールにキャンセルを押されたかを示すフラグをprivateで宣言して、2つの関数を追加します。ひとつはfrmMainからキャンセルのフラグをセットする関数、もう一つはclsSubからキャンセルを押されたかをチェックするための関数です。 ------------------------------------------------------ 標準モジュールの中 private blnCancelFlg as boolean Sub subSetCancelFlg(blnFlg as boolean)  blnCancelFlg = blnFlg End Sub Function funCheckCancelFlg() as boolean  funCheckCancelFlg = blnCancelFlg End Function ---------------------------------------------- という感じで作って呼び出すようにしてはどうでしょうか?

bou7
質問者

補足

一緒に考えてくださって、本当にありがとうございます。 いっそのこと、標準モジュールにPublic変数を作り、clsMainからその値を変更して、frmMain、clsSubでその変数を参照しようかと思ったんですが、どうでしょうか? こういうやり方って、まずいのでしょうか? ちなみに私が今修正しているソース(別の人作成。でも辞めてしまったので聞けません・・・)では、標準モジュールにPublic変数はないので、「こういうやり方をしてはいけないのかな?」と思って避けて来たのですが、一般的にはどうなのでしょうか?

その他の回答 (4)

  • ape5
  • ベストアンサー率57% (85/148)
回答No.5

グローバル変数は避けた方が良いかと思います。 例えば、あるグローバル変数に値を設定するだけだとしても、将来その値に制約が加わったときに、グローバル変数を設定しているところをすべて直さないといけないが、関数をラッパーとして設定していれば、その関数の中でその制約を書き込めば終わりです。 一般的にグローバル変数は推奨されてないですね。 この場合は、グローバル変数を使わなくてもできると思うので、使わないでいた方がよろしいかと思います。

bou7
質問者

お礼

何度も返信して頂き、どうもありがとうございました。 グローバル変数は良くないと言う事でしたので、No.4の回答で教えて下さったように、標準モジュールを使うことにしました。 何度も一緒に考えて下さり、本当に、どうもありがとうございました。

  • ape5
  • ベストアンサー率57% (85/148)
回答No.3

いえ、手はあると思います。 今から述べることに関してですが、モジュール変数のライフタイムについてちょっと自信がないので、ある一つの例を示します。もしダメな時は、標準モジュールのほうに変数を書き換えるなど試してみてください。 frmMainにある関数を作ります。例えばfunCheckCancelFlg()としましょう。この関数は何をするのかというと、キャンセルボタンが押された時に立つフラグを返します。何をしたいかというと、clsSubのループの中で毎回この関数を呼びます。そして戻り値を見てキャンセルされたかをチェックし、キャンセルされたら処理を中断するのです。 以下のような感じでよろしいかと。 -------------------------------------------------------- ・frmMainの中 private blnCancelFlg as boolean function funCheckCancelFlg() as boolean  funCheckCancelFlg = blnCancelFlg end function ・clsSubの中 sub 質問者さんの処理の関数  Do   if frmMain.funCheckCancelFlg = true then    exit Do   end if  Loop end su ----------------------------------------------------------- かなり怪しい記憶で書いてるのでコマンドとか文法とか間違ってると思いますが、その辺はくみ取って挑戦してみてください。

bou7
質問者

補足

返信ありがとうございます。 frmMainから参照しているclsSubより、逆にfrmMainを参照したら、循環参照になってしまうのではないかと心配なのですが、どうでしょうか?

  • ape5
  • ベストアンサー率57% (85/148)
回答No.2

通知っておっしゃってるよなので、イベントを使っているということでよろしいのでしょうか?私はイベントを使ったことがないのでよくわからないのですが、考えられる原因に、次のようなのがあると思います。 clsSubである処理をしている。これが長い時は10分とかかかるそうなので、この間はほかのイベントが発生しても見に行かないのだと思います。例えばこういうのがあります。 ある処理をしているのですが、その進行状況に合わせてプログレスバーを更新したい。だけど、値を設定してもプログレスバーが進まない、というのがあります。これは、ずっとメインの処理をしていて、画面更新をしないのです。これを回避する手として、DoEventを使うのがあります。 DoEventが発生すると、現在行っている処理をちょっと中断してほかのイベントとかないか見にいくのです。そして、この場合はプログレスバーが更新され、メインの処理を続けるのです。 同じようにループの中でDoEventを使っていてはいかがでしょうか。うまくいくかはわかりませんが、試してみる価値があるかとおもいます。 がんばってください。駄目でしたらまた書き込みお願いします。

bou7
質問者

補足

返信ありがとうございます。 DoEventsは入れているのですが、駄目です。 clsMainからfrmMainへはプロパティの値を単に変更しているだけです。 諦めた方が良いでしょうか・・・?

  • ape5
  • ベストアンサー率57% (85/148)
回答No.1

clsMainとfrmMainでできるなら同じようにすれば良いのではと思うのですが、それはどうやってるのでしょうか? 自分が考えるに、あるキャンセルされたかを示すフラグを用意します。A.exeの方でキャンセルが押されたら、このフラグを立てます。clsSubの処理の中でループの中で毎回そのフラグをチェックし、フラグが立っていたら中止するってのはどうでしょうか。

bou7
質問者

補足

返信ありがとうございます。 clsMainからfrmMainへ通知する方法は、  evtFrmMain.CancelFlag = 1 としているだけです。 clsSubにキャンセルが通知されてからの処理は、ape5さんが仰ったようにしているのですが、まず最初に絶対必要な、キャンセルが通知できません。 clsMain←→frmMain間と同様に記述しても、clsMainからclsSubへ通知出来ないし、代わりにfrmMainからclsSubへ通知しようとしても、clsSub内での処理が終了しないと、通知することが出来ません。 clsSubでの処理を呼んでいるのはfrmMainだけなので、clsSubでの処理を全てfrmMainに移行しようかとも思うのですが、どうでしょうか? ※元々このアプリは別の人が作り、自分は障害対応をしているので、frmMainとclsSubを分けた理由も分かりません・・・

関連するQ&A

専門家に質問してみよう