• ベストアンサー

終了してもプログラムが実行したまま(VB)

非常に時間のかかる繰り返し処理を行なうプログラムを作りました。どのくらい、プログラムが進行しているのかわかりやすくするため、 Progress.Show でProgressという名前のフォームを表示し、そこに、プログラムが何%終わったのか表示するようにしました。 プログラムはDo Loop文が使ってあるので、何%終わったのかを表示するためにLoopした回数を取得して、それをフォームに表示することにしましたが、どこかで調べたら機械は、Do Loopのあいだはフォーム上に文字を表示するのに手が回らないからDoEventsを使ってイベントを実行させなさい、といわれました。 そこまではうまくいきました。プログラムを実行すると、プログラムが実行されて何%終わったかもちゃんと表示できるようになりました。 ところが、プログラムの実行中にフォームの右上の×ボタンを押したところ、フォームは画面から消え、プログラムが終了したように見えるのに、VB Editorでは[実行中]となっており、終わってくれません。ずっとDo Loopが実行されたままです。 Private Sub Form_Terminate() のところに Unload Progress と書いても、「Unloadメソッドは使えません」などというエラー・メッセージが出ます。(フォーム上にボタンを置き、そこをクリックするとUnloadするようにしてみましたがやはり同じことを言われました。) 原因は何でしょうか? フォームをUnloadする、ということの意味をちゃんと理解していないのでいけないのだと思うのですが、調べてもよく言っていることがわかりません。 よろしくお願いします。

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

  • ベストアンサー
  • piyo2000
  • ベストアンサー率49% (144/293)
回答No.4

>いったんLoopに入ったら、中断させる方法がない、ということでしょうか。 Exit Doで抜けられますが・・・(^^; というより、この場合無限Loopは使うべきじゃないですね。 #2さんが言われるようにキャンセルボタンを置いて キャンセルボタンではキャンセルフラグをON(TRUE)にします。(キャンセルフラグはモジュール変数) Do While (キャンセルフラグ=FALSE and 100%じゃない ) 表示処理 DoEvents Loop のようにします。 # Untilを使うと分かりやすいですがあえてWhileで。 >Timerをつかうと、途中で中断できるのでしょうか。 考え方は上記と一緒です。 Timerイベントでキャンセルボタンが押されたかどうかをチェックすればいいだけです。 #1さんが(描画にも)Timerを使ったほうがいい、というのはタスクマネージャでCPU使用率を表示させてみると分かると思います(^^; また、この原因はDoEventsを使っているから、なんですけどね(^^; DoEventsを使うと、時間が掛かる処理中にも別のイベントが発生(この場合はUnload)するからで、なおかつLoopを抜けていないからですね。 Do Whileを使うなら、UnloadイベントにもキャンセルフラグをONにするコードを書けばループを抜けてくれるので終わってくれるはずです。 #3さんの「Endを使えば」というのは手っ取り早く確実な方法ですが、個人的には使うべきじゃないと思います(^^; このケースでは関係ないですが、オブジェクトの寿命に無頓着になりがちだからです。

crooked_man
質問者

補足

BLUEPIXYさん、kahaさん、piyo2000さん、ありがとうございます。 いろいろと教えていただきましたが、僕は重大な勘違いをしていました。Unloadというのは、「全部やめなさい」という意味だと思っていたのです。ですからUnloadを書いた時点で何もかも終わるはずだと思っていたのです。 ところがpiyo2000さんのお答えの中で、UnloadイベントにフラグをOnするコードをかけば、、、というのがありました。Unloadしたら全部終わるのだからUnload後にコードを書いても無駄では?と思ったのですが、Unloadはそういうことではないのですね?? >Do While (キャンセルフラグ=FALSE and 100%じゃな >い ) >表示処理 >DoEvents >Loop >のようにします。 たいへんわかりやすいです。思いつきませんでした。ということは、UnloadしたときにキャンセルフラグをTrueにするようにしてもいいということですね。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (3)

  • kaha
  • ベストアンサー率23% (41/177)
回答No.3

> Unload Progress > と書いても、「Unloadメソッドは使えません」 Progress.Showと呼び出し元が先に終了してしまっているからではないでしょうか? 呼び出し元で×ボタンで終了直前に呼ばれるQueryUnloadイベントの処理にステートメントの End を実行するよいうにすればどうでしょうか?

全文を見る
すると、全ての回答が全文表示されます。
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

>ユーザがいやになったら中断できるようにしたい Progressフォームにキャンセルボタンを置いて 押されたら中断するようにすればいいでしょう また、×ボタンを押したら、キャンセルボタンクリックイベントを実行するようにしておけばより良いと思います。

全文を見る
すると、全ての回答が全文表示されます。
  • todo36
  • ベストアンサー率58% (728/1234)
回答No.1

>原因は何でしょうか? プロセスが動いたままだから。 >ずっとDo Loopが実行されたままです。 これです。 Loopから抜けなければプロセスは終わりません。 >Do Loopのあいだはフォーム上に文字を表示するのに手が回らないからDoEventsを使ってイベントを実行させなさい、といわれました DoEventsだけでは重いのでSleepも入れた方がいいでしょう。 いや、Loopで回すのではなくTimerを使うのがよいと思います。

crooked_man
質問者

補足

ありがとうございます。 ということは、いったんLoopに入ったら、中断させる方法がない、ということでしょうか。 また、Timerをつかうと、途中で中断できるのでしょうか。かなり時間のかかる処理なので、ユーザがいやになったら中断できるようにしたいと思っています。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • コンパイルしたプログラムが終了しないのですが

    VB6.0で教えてください。 コンパイルしてできたプログラムを実行し、フォームの右上にあるコントロールボックスから閉じると、フォームは非表示になるものの、プログラム自体がメモリに残っているようです。 完全に消すには何かコードを追加する必要があるのでしょうか?

  • vb2005でプログラムをとめるコードは?

    お世話になります。 vb2005でプログラムに5秒間、時間をとめようとおもいます。 これだとTimerにエラーがでてしまいます。 ('Timer' は型です。有効な式ではありません。) どこをどうなおせばエラーがでなくなるのでしょうか? 教えてください。お願いします。 Dim sngSt As Single sngSt = Timer Do While Timer - sngSt < 5 DoEvents() Loop

  • [VB6] フォームを閉じる方法について

    お世話になります。 VB6で別フォームを起動する際の親フォームの閉じ方について 質問させてください。 呼び出し元フォームからShowメソッドで別フォームを起動すると、 呼び出し先のフォームでマウスのカーソルが砂時計表示になってしまいます。 (呼び出し元のフォームはUnload Meで閉じています。) [Form1の処理] Private Sub Button1_Click() Form2.Show Unload Me End Sub ※Form1は呼び出し元。Form2は呼び出し先。 原因について、どなたかご存知の方がいらっしゃいましたら、 ご教授願えますか?

  • VB2005 Do Loopについて

    VB2005 でDo Loopを使用していますが、このDo Loop内の処理をしている時にイベント(例えばボタンをクリック)が発生した場合、その処理をしたいのですがどうすれば良いでしょうか? VB6の時は、DoEventsを使用していましたが、VB2005でも使用できるのでしょうか? ご存知の方がいらっしゃいましたら、教えて頂きたいのですが。 よろしくお願いします。

  • タスクスケジューラでVB6のプログラムが実行しない

    VB6で作ったプログラムをWindows7において、タスクスケジューラで起動させたが、実行しない。 フォ-ムは1個だけで、その中のACTIVATEから、同フォーム内のルーチンを呼び出して目的の動作をさせるようになっています。手動で起動させると、目的の動作をして終了するが、タスクスケジューラではフォームを表示した状態で止まっている。そのフォームをクリックすると目的の動作を行う。なお、フォームはその時実行されている別のVB6のフォームの前面[最前面)に表示されている。目的は1日1回自動的に特定ファイルの状態を調べたいだけです。 よろしくお願いします。

  • プログラム実行時の確認は

    今まではコンボボックス内をセレクトしたあとすぐに計算を実行して表示するプログラムだったのですが、テキストボックスにデータを入力後ボタンを押したときに計算を行うように変更しようとして、新規に作成したボタンの「Private sub Command1_Click()」にコンボボックス内に書いていたプログラムをコピーして実行したのですが、ボタンを押してもエラーで止まるわけでもなく、しかし、実行結果を表示するでもなく、まるでループにでも入っているようなのですが、実行中にどこでどうしているか確認する方法を教えてください。

  • フォームを閉じないようにする VB6 SP6

    VB6 でプログラムを作成中です。 プログラムを実行して、フォームが立ち上がった所で右上の×を押し、画面を閉じようとします。 そこで以下のコードで、もし×が押されたらvbYesNoメッセージボックスを表示させ、もし「いいえ」が押されたらフォームを閉じないようにし、実行画面を維持したいのです。 しかし、Exit Sub ですとプログラムが終了してしまい、困っています。宜しくお願い致します。 Private Sub Form_Unload(Cancel As Integer) 'フォームを閉じる Dim last As String last = MsgBox(" プログラムを終了させますか?", vbYesNo, "終了確認1") If (last = vbYes) Then Dim last2 As String last2 = MsgBox(" 本当にプログラムを終了させますか?", vbYesNo, "終了確認2") If (last2 = vbNo) Then Exit Sub End If End If If (last = vbNo) Then Exit Sub End If End Sub

  • VB6(SP5) 無限ループ

    VB6(SP5)で、プログラミングをしております。 コマンドボタンをクリックすると、別のフォームを開く仕様にしております。 下記のプログラミングです。 ブレイクポイントで、テキストボックスにフォーカスが戻る事は、確認しております。 が、再び、同じフォームが開きます。要するに無限ループになってしまって いるのです。しかも、開発マシン(Win2000)では、再現しません。 実際のあるマシン(Win98SE)のみ再現します。(全てではありません) 助言の程、よろしくお願い致します。 Private Sub CB_Code_Click() Form1.iDoF = True Form1.Show Do While Form1.iDoF = True DoEvents Loop Set Form1 = Nothing Form_Activate DoEvents Text1.SetFocus End Sub

  • アップロードができない

    ローカルHDDにあるファイルをネット上にアップロードしたいため下記コードを作成したのですがコピーする事ができませんでした。 PC環境:WindowsXP ProSP1、VB6.0SP6です。 どうすればアップーロードできるのでしょうか? どなたか御願い致します。 ///////////////////////////////////////////////////// Private InetState As Boolean Private InetError As String Private Sub Command1_Click() Inet.RequestTimeout = 2 Inet.UserName = "*" Inet.Password = "***" Inet.Execute "*", "PUT c:\11.txt 11.txt" Do DoEvents Loop Until InetState If InetError <> "" Then MsgBox InetError InetState = False Inet.Execute "*", "CLOSE" Do DoEvents Loop Until InetState InetState = False Inet.Execute "*", "QUIT" Do DoEvents Loop Until InetState Inet.Cancel Unload Me End Sub ///////////////////////////////////////////////

  • VBプログラムを終了させないようにするには

    VB2005 WindowsXPでの開発を考えています。 メニューボックスは表示せず、終了ボタンからの終了にはパスワードの入力を求めるようにします。 しかしこれだけでは、タスクマネージャ等からの強制終了ができてしまいます。 強制終了も不可能にすることは可能でしょうか? また、できるのであればプログラム起動中は、Windowsの操作(エクスプローラやスタートメニューなど)をできないようにしたいと考えています。現状ではモーダル状態のフォームを最大化して表示させようと思っていますが、他に良い方法を御存知でしたらお願い致します。

このQ&Aのポイント
  • 印刷すると文字化けするため、プリントアウトがうまくできません。
  • Excelで領収書を作成する方法も上手くできません。
  • 富士通FMVでのプリントアウトのトラブルについて教えてください。
回答を見る

専門家に質問してみよう