はじめに
Excelでは、WScriptオブジェクトを使ってコマンドプロンプトを使えるので、Pythonを実行する事が可能です。
WScriptオブジェクトには、RunメソッドとExecメソッドがありますが、両者の違いは以下の通りです。
Runメソッド
・実行するアプリケーションのウインドウスタイルを指定できる
・同期、非同期を指定できる
Execメソッド
・実行するアプリケーションと通信して結果を取得できる
ここでは簡単なPythonのコードを2つ方法で試してみましょう。
今回使用する Python コード
今回実験するPythonのコードは、3秒待ってから「Hello Python」と表示する簡単なコードです。
# testPython.py (Pythonコード)
import time
time.sleep(3)
print('Hello Python')
このプログラムを使って挙動を確かめてみましょう。
testPython.py という名前を付けて保存しておきます。
後でファイルの場所もフルパスで必要になります。
Runメソッド(WScript.Shell)
Runメソッドでは、実行するアプリケーションのウィンドウスタイルを第2引数に指定できますが、今回はPythonのコマンドなので必要ありません。
第3引数には、同期、非同期をBooleanで指定できます。同期とは、起動したアプリケーションの終了を待つかどうかです。Falseを指定するとアプリケーションが終了するのを待たずにVBAの処理に戻ってきます。Trueを指定した場合は、アプリケーションの終了を待ってVBAに処理が戻ります。
Sub wsh_run()
Dim myCommand As String
Dim wsh As Object
Dim result As Integer
Set wsh = CreateObject("WScript.Shell")
'実行するコマンド
myCommand = "python c:\pythonTest\testPython.py"
'コマンドを同期実行
result = wsh.Run(Command:="%ComSpec% /c " & myCommand, WindowStyle:=0, WaitOnReturn:=True)
If result = 0 Then
MsgBox ("正常終了")
Else
MsgBox ("異常終了")
End If
Set wsh = Nothing
End Sub
実行するコマンドは、“python c:\pythonTest\testPython.py“ としています。
今回はPythonにパスが通っている状態を想定ていますので、もしパスが通っていない場合は、python.exe のフルパスを指定する必要があります。
pythonコマンドの後には上記で作ったpythonコードをフルパスでしていします。
こちらはご自身の環境で適宜変更してください。
WScript.Shell を wsh で受けて、Run メソッドを実行しています。
第一引数のCommand にある「“%ComSpec% /c “」はコマンドシェルの 9x系と2000系を自動判定するための記述になります。
第3引数の WaitOnReturn:=True で同期処理を指定していますので、pythonプログラムが終了してから処理が戻ってきます。
Runメソッドの戻り値をresultで受けて結果を判定します。
実行すると、3秒後にメッセージボックスに「正常終了」と表示されるはずです。
第三引数で WaitOnReturn:=False とした場合は、実行後すぐにメッセージボックスが表示されます。
この時Pythonプログラムは実行中ということになります。
いずれの場合も、「Hello Python」という表示は取得できません。
Execメソッド(WScript.Shell)
Execメソッドでは、Runメソッドと違いPythonコードの戻り値を取得する事ができるようになります。
Sub wsh_exec()
Dim wsh As Object
Dim wExec As Object
Dim Cmd As String
Dim result As String
Set wsh = CreateObject("Wscript.Shell")
Cmd = "python c:\pythonTest\testPython.py"
Set wExec = wsh.Exec("%ComSpec% /c " & Cmd)
Do While wExec.Status = 0 'コマンドが終わるまで待機
DoEvents
Loop
result = wExec.StdOut.ReadAll '結果を文字列で取得
MsgBox result
Set wExec = Nothing
Set wsh = Nothing
End Sub
途中までは、Runメソッドと一緒です。
WScript.Shell を wsh で受けて、Execメソッドを実行しています。
Execメソッドでは、戻り値をWshScriptExecオブジェクトで受けてプロパティを参照する形になります。
コマンドが終了すると、Statusプロパティが 0 になるので、Do While ループを使って終了を待ちます。
最後に、StdOut.ReadAll で結果を取得できるので、それをメッセージボックスで表示させています。
まとめ
ExcelVBAでPythonを実行させるなら、戻り値を受け取れるExecメソッドの方が便利かもしれません。
ただ、StdOut.ReadAllでは、改行も含めた全文となるため取得後にSplit関数などで切り分ける必要性があるかもしれません。
Pythonが出力する結果を取得したい場合は、テキストファイルやCSVファイルを吐き出させて、後からそれを参照する方法がもあります。
もし、Pythonプログラムを起動して終わりという事であれば、Runメソッドでも良いでしょう。
この場合は、プログラムの終了を待たないでVBAに戻ってくる事も可能です。
シチュエーションに合わせて工夫してみましょう。










コメント