以前こちらの記事で参考にしたソースコードでは一部うまく行かないケース(ps1スクリプトに与える引数が正しく渡せない)があったので動くように改善してみました。
Excel VBAからPowershellスクリプトを引数付きで実行する方法について解説します。関数化して、汎用性を持たせることで、複数のスクリプトを扱う場合やpowershell側の期待する引数の数が幾つの場合であっても簡単に実行できる様にしています。
1.VBAからのPowershell呼び出し関数
以下がVBA側のコードになります。
Public Function RunPowerShell(intWindowStyle As Long, bWaitOnReturn As Boolean, psFilePath As String, ByVal args As Variant) Dim cmdline As String cmdline = Chr(34) & "powershell" & Chr(34) & " -ExecutionPolicy RemoteSigned -File " & Chr(34) & psFilePath & Chr(34) cmdline = cmdline & " " & Chr(34) & Join(args, Chr(34) & " " & Chr(34)) & Chr(34) Dim objWSH As Object Set objWSH = CreateObject("WScript.Shell") Dim ret As Variant ret = objWSH.Run(cmdline, intWindowStyle, bWaitOnReturn) RunPowerShell = ret End Function
上記の関数を標準モジュールに記載しておくことで、マクロ内で関数としてPowershellスクリプトを実行することができます。
2.VBAでの使い方
以下はサンプルコードになります。4つの引数パラメータをC:\example.ps1に渡す場合の呼び方を示しています。
Sub Macro1() '配列引数用動的変数 Dim arrArgs() '4つの引数パラメータをC:\example.ps1に渡す場合の呼び方 ReDim arrArgs(4) arrArgs(0) = 1 arrArgs(1) = 2 arrArgs(2) = 3 arrArgs(3) = 4 arrArgs(4) = "Mojiretsu" result = RunPowerShell(1, True, "C:\example.ps1", arrArgs) ' End Sub
上記のサンプルコードを実行することで、引数付きでPowershellスクリプトが実行され、result
に戻り値を受け取ることが可能になります。
3.「RunPowerShell」のポイント
①RunPowerShell側でexample.ps1の想定する引数が幾つあっても良い様に、配列で引数をとっている。②また、配列は通常参照渡ししか出来ないものの、
ByVal args as Variant
とする事で、配列を値渡し出来るテクニックを使っています。(配列の引数を定義して配列をそのまま渡すと、配列の要素内に配列が格納され、2次元配列になってしまい、うまく動かせなかったため。)
③ps1の引数がフルパス等を期待している場合、スペースが含まれるとうまく動かないので、
cmdline = cmdline & " " & Chr(34) & Join(args, Chr(34) & " " & Chr(34)) & Chr(34)
という具合にJoin関数で" "という文字列で結合し、最後にさらに”=Chr(34)をつなげるという処理にしています。
4.まとめ
この記事を通じて、Excel VBAからPowershellスクリプトへ引数を正しく渡す改善版の方法をご紹介しました。以前のソースコードでは、引数の渡し方に一部問題があり、特定のケースでスクリプトが正常に動作しないという課題が存在しました。
しかし、今回提供したソースコードでは、引数を配列として扱い、それを適切にフォーマットしてスクリプトに渡すことで、この問題を解決しています。このテクニックにより、任意の数の引数を含むPowershellスクリプトを、スペースを含むパス名でも確実に実行できる様になりました。
0 件のコメント:
コメントを投稿