前提・実現したいこと
VBAからWshShell等により他アプリケーションを起動する場合に終了待ちを行いたい。
同期呼び出しではVBAが固まってしまうので、非同期で呼び出したいと考えており
終了時にイベント発生というのが理想です。処理が複雑になるのも避けたい感じです。
要件としてはpythonのプログラムを起動し結果を取得するものです。
質問は
今のままで問題ないか、それとも何か良い別の終了待ちの方法はないでしょうか。
という内容です。
ちょっとしたことでも良いので何かあれば回答をお願いします。
発生している問題・エラーメッセージ
現在使っている方法は「試したこと」に記載した内容なのですが
以下の部分
VBA
1 Do While tExex.Status = 0 2 DoEvents 3 Loop
ここのループがCPUをそれなりに使ってしまうので良くないのでは。
と思っている次第です。静かに待ちたいのです。
.Netだと終了のイベントが取れない場合は
Timerのコンポーネントをつかって終了判定をする所だと思います。
1秒間に1回程度の判定であれば、それほど騒がしくないと思うので。
試したこと
VBA
1Public Event EndCommand(ExitCode As Long) 2 3Public Sub Exec(cmd As String) 4 Dim tWsh As IWshRuntimeLibrary.WshShell 5 Dim tExex As WshExec 6 Dim tExitCode As Long 7 Set tWsh = New IWshRuntimeLibrary.WshShell 8 9 ' 処理呼び出し 10 Set tExex = gWsh.Exec(cmd) 11 12 ' 終了待ち 13 Do While tExex.Status = 0 14 DoEvents 15 Loop 16 17 ' 終了イベント呼び出し 18 tExitCode = tExex.ExitCode 19 Set tExex = Nothing 20 RaiseEvent EndCommand(tExitCode) 21 22End Sub
省略したコードですが、これをクラスモジュールに記載し
呼び出し側でWithEventsで終了時の処理を記述
という風にしています。
参照設定はWindows Script Host Object Modelです。
(追記 2021/04/11)
終了時にコールバック関数が呼ばれたりイベントが発生したりというようなものがあればいいのですが
と考えているとTimerがVBAにもあればなんとかなるような気がしたので検索すると
Application.OnTime というのを見つけました。これはこれで使える気がします。
あと
timeSetEventについて記述がある
これは使えるのかどうなのか。
「処理が複雑になるのも避けたい感じです」と言いましたが
少しぐらい複雑でも、それをひとまとめにしてクラスにしたり
決まった関数が呼び出されるようにするというのは許容範囲内だと考えています。
(解決後の追記)
sleep 1ということで静かに待つとまでは言えないですが
cpu負荷がほぼ0%に下がった為、これで運用上は問題ないと判断しました。
Application.OnTimeの方が静かに待つ。という条件には沿う気はしますが
こちらは、とりあえず使い方だけ押さえておくという事にしておきます。
補足情報(FW/ツールのバージョンなど)
Windows10
Office365
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2021/04/12 00:19 編集