- ベストアンサー
EXCEL VBAマクロの実行優先度を下げたい
いつもお世話になっております。 EXCEL VBAであるマクロを実行させています。 このマクロは終了するのに丸1日以上掛かるもので、それを実行している間、EXCEL.EXEのCPU使用率が100%になってしまいます。 私の所有するPCパワーが乏しい&所有PCが1台だけのため、このマクロを実行している間、EXCEL以外の他の作業の動作がとても遅くて困っています。 例えば、テキストエディタで文字を打って変換するのに数秒かかったりします。 タスクマネージャでEXCEL.EXEのプロセス優先度を下げることができるのは知っていますが、以前別のマクロでそれを実行して他の作業をやっていた時にEXCELが強制終了された経験があり、私のPCではタスクマネージャによるプロセス優先度の変更はシステムが不安定になることに繋がるようです。 ですので、できることなら、実行中のVBAマクロのみ優先度を下げたいんですが、そのようなことは可能なのでしょうか。 よろしくお願いいたします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
#2です。 Sleepはループの先頭などに入れます。 確かにSleepを入れることで多少処理に時間はかかるようになるかもしれません。 発行間隔にもよりますが、Sleep(10)とかにすれば一回あたり10ms程度の休止ですから100回コールすれば1秒遅くなることになります。 100万回コールすれば3時間近く遅くなってしまいますね。 設定変更して何回同じ処理を繰り返すのかはわかりませんが、 Sleep(1)でも1000万回も呼べばそれだけ遅くなります。 その意味でIDLE状態のときにはずーと動いてくれるSetPriorityClassのほうがいいかもしれません。安定性については分かりかねますが。 SetPriorityClassについてはここに解説が。 http://yokohama.cool.ne.jp/chokuto/urawaza/api/SetPriorityClass.html 通常に戻すにはこれでOKなはずです。 Call SetPriorityClass(GetCurrentProcess, NORMAL_PRIORITY_CLASS) ただ、1つのPCで長い処理をしながら割りこみで別の処理をしようっていうんだからどちらにしても多少の遅れは発生すると考えられます。 あとは処理を見直すこと。1日流しっぱなしというのは相当な処理量です。 現段階では完璧とは思っているでしょうけど、理解が深まれば削れるところも出てくるかもしれないし、そもそも計算の一部が必要なくなることもありえますので。
その他の回答 (3)
- n-jun
- ベストアンサー率33% (959/2873)
直接の回答ではないですが。 >このマクロは終了するのに丸1日以上掛かるもので、 ここの見直しはもう出来ないのかな?と感じました。
補足
n-jun様、回答ありがとうございます。 残念ながら、これ以上の高速化は難しいようです。 No.2のkenpon24様への補足でも書きましたが、あるプロシージャ内のパラメータ3つを変化させてfor分で繰り返し処理を行わせるマクロでして、あるプロシージャというのはパラメータが決まっていれば、1秒足らずで終了するものです。 パラメータの最適化に丸1日は掛かると言うことです。 VBAの高速化に関しては以前OKWaveで質問をさせて頂いて、回答頂いた内容はすべてやり尽くしたと思っています。
- kenpon24
- ベストアンサー率64% (66/102)
おそらく外部からプロセスの優先度を下げると処理が中断されたりして不安定になるんだと思います。 それよりも処理中に適度にSLEEPを入れてみましょう。 CPU使用率100%を回避する方法 http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=35231&forum=7 SLEEPの使い方 http://www.asahi-net.or.jp/~ef2o-inue/api/sub08_01_060.html
補足
kenpon24様、回答ありがとうございます。 参照URLを見たところ、私のマクロとは違う処理に対してCPU使用率100%を回避しているようです。 私の説明不足でした。 私のマクロは1つのプロシージャ(これ自体は1秒程度で終了)に対して、パラメータが3つ存在して、それらパラメータをfor文で順に変化させて処理をさせるマクロですので、いったんマクロを実行するとずーっと処理を続けていることになります。 定期的にある処理をさせるマクロのCPU使用率とは意味合いが異なるように理解しています。 ですので、ただでさえ時間が掛かるのにSLEEPの分だけ処理時間が増えるという風に理解しましたが、どうでしょうか。 No.1のyuji0401様に提案頂いた方法が私のやりたいことに即しているのではないかと考えております。
- yuji0401
- ベストアンサー率9% (28/284)
Private Const IDLE_PRIORITY_CLASS = &H40 Private Declare Function GetCurrentProcess Lib "kernel32" () As Long Private Declare Function SetPriorityClass Lib "kernel32" (ByVal hProcess As Long, ByVal dwPriorityClass As Long) As Long Sub ボタン1_Click() Call SetPriorityClass(GetCurrentProcess, IDLE_PRIORITY_CLASS) '1日かかる処理 End Sub これじゃダメ?
補足
yuji0401様、回答ありがとうございます。 お恥ずかしい限りですが、上記の内容がさっぱり理解できません。 よろしければ詳しい説明を頂ければと思います。 とりあえず私の理解は別にして、そのままコピペで優先度が「低」になったのはタスクマネージャで確認できましたが、タスクマネージャを使って優先度を「低」にするのと何が違うのでしょうか。 上記コードを追加することでシステムの不安定さを回避しつつ、優先度を下げることができるということなのでしょうか。 試しに処理の繰り返し回数を減らしてすぐに終わるように設定してマクロを実行、終了させたところ、優先度が「低」のままになっているんですが、これを「通常」に戻すにはどうすればいいのでしょうか。 よろしくお願いいたします。
お礼
kenpon24様、丁寧な解説、ありがとうございます。 今回はSetPriorityClassの方でやってみようと思います。 Sleepの方も場合によっては有効な手段だと思いますので、参考にさせて頂きます。 処理の見直しは私も必須だと考えております。 ただ、現時点ではいいアイデアが出てこないので、このままのプログラムでやっていこうと思います。 その間に理解を深めていきたいと考えています。 本当にありがとうございました。