起動と監視
Excel の VBA を使ってのVboxManage の起動は簡単です。
- WshShell オブジェクトを使ったコマンドラインの起動
- WshExec オブジェクトを使った起動中の監視と進捗状況の画面表示
WshExec オブジェクトは起動したアプリケーションと通信できるのが Excel VBA の Shell 関数と違うところです。
VBA Sample :
Dim objWSH As New IWshRuntimeLibrary.WshShell
Dim objWSHExec As IWshRuntimeLibrary.WshExec
Dim sStdErr As String
Dim sStdOut As String
'DOS起動
Set objWSHExec = objWSH.Exec(sCMD)
With objWSHExec
'DOS終了判定
Do While .Status = 0
Sleep 100 '0.1秒
'進捗状況を画面に表示
sStdErr = sStdErr & .StdErr.Read(1)
TextBox1.Text = sStdErr
DoEvents
Loop
sStdErr = sStdErr & .StdErr.ReadAll
sStdOut = sStdOut & .StdOut.ReadAll
'終了状態を画面に表示
TextBox1.Text = sCMD & _
vbCrLf & vbCrLf & sStdErr
DoEvents
If .ExitCode = 0 Then
TextBox1.Text = TextBox1.Text & _
"正常終了。"
Else
TextBox1.Text = TextBox1.Text & _
"エラー発生。 (ExitCode:" & .ExitCode & ")"
End If
DoEvents
End With
'オブジェクトの強制開放
Set objWSHExec = Nothing
Set objWSH = Nothing
問題点
上記VBAスクリプトでの最大の問題点は、太線で示した部分。
'進捗状況を画面に表示
sStdErr = sStdErr & .StdErr.Read(1)
「 .StrErr.Read(1) 」はコマンドラインで起動した VboxManabe の進捗状況のテキストが取得する為の命令。
ココは非同期で無く、同期処理で動く。
処理状態が進展してテキストが取得出来るまで、制御が戻ってこない。
つまり画面上では以下の様になる。
「応答なし」はWindowsシステムが表示している。
フリーズと同じ状態に一時的になる。
但し、VboxManabe の進捗状況のテキストが取得できると制御が戻ってくるので、その時に「応答なし」は消えて、画面内容は更新される。
「応答なし」はダメですね。
※この状態が何度も起きると Windows OS (Windows 7)自体も少し不安定になった。(怖
解決方法 (案
実際の技術的な面での検証はこれからだが、非同期で VboxManage の進捗状況を監視するしか手はない。
残念だがVBA環境下だけで非同期処理を行うのは技術的にあまりにも高度すぎ、ロジック検証も難しくなる。
よって検討した結果、以下の方法で監視と状態の表示を行うとする。
- Excel VBA から VboxManageのコマンドラインを引数にしてvbsファイル を起動する。
- vbs ファイルでWSH を使って
- VboxManageのコマンドライン起動
- 処理終了までの監視
- 処理途中の進捗状況をテキストファイルで随時出力する
- 終了したら、終了状態を書いたテキストファイルを出力する
- Excel VBA は vbs ファイルから出力されるテキストファイルの内容を定期的に読み込んで、状態を監視しながら進捗状況を画面に表示する。
WSH の vbsファイルはExcel VBA から見れば非同期で処理していると同じになる。(はず
WSH 自体は初めてだが恐れることは無い。
ネットには沢山の技術情報が有る。
注意点
動作を監視する vbsファイル 内で「 .StrErr.Read(1) 」を行うと一時的に制御が戻ってこなく、フリーズと同じ状態になる。
- Windows OS が不安定にならない
- その時に他のWSH (vbsファイル)が動作する
のを確認しないといけない、と思っている。
< TOPへ >