- ベストアンサー
Excel VBA プログラムを止める命令
以前にも同じ趣旨の質問をしたのですが、 一度締め切った後も結局解決せず、少し自分でも質問の仕方が まとまって来たと思うので、再度質問させてください。 Ontimeメソッドで、あらかじめ時刻を指定し(これは複数あります) 印刷をかけさせるというプログラムをつくっているのですが、 そのプログラムを丸ごと止めるボタンというのをつくりたいのです。 Crtl+Breakをsendkeyで送るというのを考えたのですが、 私の環境(win2000+Excel2002)では、Crtl+Breakを押してもEscを押しても 反応している様子がなく、マクロの自動記録でも記録されないので、 果たしてそれを設定して有効かどうかもわからず、 具体的にどう記述すれば十分なのかも調べ切れませんでした。 Ontimeをピンポイントで止める、というのも 前回の質問でいただいた回答の中にあったのですが、 Ontimeというより、プロシージャもしくはモジュールを すべて停止させたいのです。 考える糸口だけでも、何かアイディアありましたらお願いいたします。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 前回というのは、これですか? http://oshiete1.goo.ne.jp/kotaeru.php3?q=2386642 できるだけ、情報は、多くお願いしますね。 #2 さんが、紹介されていた中に、私の発言があるので書かせていただきます。 前回は、私の書いたものが理解されている様子はありませんでした。 >http://oshiete1.goo.ne.jp/kotaeru.php3?q=1592860? 止めるためには、実行する時間に対して、それぞれピンポイントでFalseにしていかなくてはいけないっていうことなのですが、そうすることによって、OnTime の息の根を完全に止めることが出来ます。 OnTimeメソッドが生きている限りは、マクロとして仕事はしなくても、たぶん、インターラプトされるはずです。インターラプトされると、他のマクロが動かなくなったりする、不都合が出てきます。 サンプル(印刷の部分は、TimeBeepにしてあります) Private TimeSchedule(9) As Date '10個の時間データ-1 Sub TimerStart() '設定用マクロ Dim i As Integer Dim myOnTime As Date For i = 1 To 10 myOnTime = Cells(i, 1).Value '"A1~A10まで時間を入力 TimeSchedule(i - 1) = myOnTime Application.OnTime TimeSchedule(i - 1), "TimeBeep" Next i End Sub Private Sub TimeBeep() '実行マクロ(サンプル・ダミー) Beep Cells(1, 3).Value = Cells(1, 3).Value + 1 End Sub Sub TimeCancel() 'キャンセル用マクロ Dim i As Integer Dim flg As Boolean On Error Resume Next '既に終わったものに対するエラー回避 For i = LBound(TimeSchedule()) To UBound(TimeSchedule()) Application.OnTime TimeSchedule(i), "TimeBeep", Schedule:=False If Err.Number = 0 And flg = False Then flg = True End If Err.Clear Next On Error GoTo 0 If flg Then MsgBox "設定を取り消しました。" '一個でも、止まれば出ます。 Else MsgBox "設定が残っていません。" End If Erase TimeSchedule() '一度取り消したものは、復活しません。 End Sub
その他の回答 (5)
私は、EXCELはほとんど使ったことがないのではずしていたら大変もし分けないのですが、 VBAというものは何らかのイベント(タイミング)で(プログラム起動を含む)動き始め、終わるまでそれを実行し続けます。 OnTime イベントというのはVBAのイベントを作成するだけです。 このイベントはエクセルが動いる間は、キャンセルをしない限り時間が来れば実行されるものです。 要するにプロシージャやモジュールをとめることと、作成したイベントをとめることはまったく別な問題です。 モジュール自体をとめてもOnTime によって作成されたイベントは動きますし、OnTime自体をキャンセルしても現時点で動いているモジュールがとまるわけではないということです。 よって、OnTime イベントをピンポイントでとめるということと、モジュール自体をとめるという双方の行為が必要になります。 質問者様はOnTimeをとめる方法が知りたいのではなく、ほかの動いているモジュールをとめる方法を探しておられるのだと思いますが、ついでに印刷もとめたいということだと思います。 それにはちょっと情報が足りません。 何がどういう風に動いているという情報が必要です。 たぶんループ作業を行っている中にDoEventsなどを入れるだけでブレークできるようになると思います。 プリントをとめるのはエクセル上に何らかのデータを残しておいて、印刷のプログラム直前にアボートさせてしまうというロジックを作っておけば、OnTime で停止させる必要はないです。
>・・・そうすると、VBA自体は動き続ける事になりますね。 Ontimeメソッド以外のイベントを使用されているのか、もしくはLoop処理をされているのでしょうか? Ontimeメソッド内で、プリント中か、停止中かをどこかに書き込んでおいて、(ANo2ではコマンドボタンのキャプションに書いていますが) 「シートに登録した時刻を書き換える」処理を行うかどうか判断する分岐をつければその処理をスキップさせることができると思います。
補足
ありがとうございます。 そうですね。単純にOntimeのみのプログラムなのではなく、 他に色々と、エラートラップのための処理などをしていて、 全体ではモジュール3つにわたるものとなっています。 的外れな答えになってしまったら申し訳ないのですが、 ここで私が書いた意味は、たとえば 何かの条件が満たされた場合にOntimeを実行するとかという仕組みに してしまった場合、それはVBAが作動している上で 「印刷の実行をする、しない」を切り分けているという事なので、 プログラム全体を止めるという目的にかなわないという事です。 Ontimeを止めたいのでも、印刷を止めたいのでもなく、 VBAを止めたい、と・・・。
- hana-hana3
- ベストアンサー率31% (4940/15541)
>・・・そうすると、VBA自体は動き続ける事になりますね。 そうですね。Ontime で呼ばれたプロシージャが呼び出されて実行に移りますが、先の文を各プロシージャに記載してあれば実行されてもすぐに終了する事になります。 >VBAは完全に止めてしまったほうが良いと思うのです。 でしたら、OnTime ・・・, False を書いたプロシージャを呼び出す事です。それ以外に完全に停止させる方法はありません。
前回の質問を見ていないので、的外れになってしまうかもしれませんがご参考になれば幸いです。 いちいち、動かす時間を覚えていなくてはいけないみたいですが、 case0で設定したものは、case1でキャンセルできるようです。 (コマンドボタンをトグルにすることができます。) case1にほかにやりたいことを書けばそれらも実行されると思います。 Private Sub CommandButton1_Click() If Me.CommandButton1.Caption <> "START PRINTING" Then a (0,"15:00:00") Me.CommandButton1.Caption = "START PRINTING" Else a (1,"15:00:00") Me.CommandButton1.Caption = "STOP PRINTING" End If End Sub Sub a(x,strTime) Select Case x Case 0 Application.OnTime TimeValue(strTime), "prtForms" Case 1 Application.OnTime TimeValue(strTime), "prtForms", False End Select End Sub
- hana-hana3
- ベストアンサー率31% (4940/15541)
>プロシージャもしくはモジュールをすべて停止させたいのです。 モジュールの中に変数やセルの値を参照して実行するかどうかを決める部分を埋め込む。 IF sheet("menu").Range("A1") = false then Exit Sub
補足
ありがとうございます。 つまり、停止ボタンをつけたいと思うならば、 ボタンを押す事で変数などが変化するようにし、 「実行しないようにする」訳ですよね。 ・・・そうすると、VBA自体は動き続ける事になりますね。 (違うのかな) 言葉足らずで申し訳なかったのですが、 プログラムを止めて何をするかと言うと、 シートに登録した時刻を書き換える」などの処理が起こり得るので、 「実行されないようにする」ではなく、 VBAは完全に止めてしまったほうが良いと思うのです。 ファイルを一度閉じてしまえば簡単なんですが、 使い心地を考えると停止ボタンをつけたいな、と思っています。 それがこんなに難しい事とは思いませんでしたが・・・。
補足
ありがとうございます。 前回の質問というのは、これです。 「Excel VBAで「プログラム実行」ボタンと「プログラム停止」ボタンをつけたい」 http://okwave.jp/qa2370027.html とり急ぎ。 お礼はまた、お答えを理解した時点で、 余裕を持って書かせていただきますね。 それまで失礼いたしますのをお許しください。