himorogiの日記

主にプログラミングに関することなど。少々ハード(電子工作)についても。

VBA から commad.com や PowerShell を呼び出す

社会人になってから30余年、ずっとプログラマでやってきたけど、もう Excel VBA とか MacOS なら AppleScriptAutomator より面倒くさい仕事(コーディング)はしたくない。

かといって Excel VBA でコーディングするのは、コードがシンプルに書けないから嫌だ。
以前は ScriptControl で JScriptVBA モジュールに埋め込んでたが、64bit 環境では使えないっぽい。

ならばいっそ、VBA 環境から PowerShell を呼びだせば pipe も使えて良いんじゃね、と調べてみた。

anosonote.hatenablog.com

thom.hateblo.jp

上記の情報とコードを元に、以下のモジュールを書いてみた。

函数 doCmdSh は command prompt と PowerShell呼び出しについて共通両方に対応している。
ただし PowerShell のコマンド文字列を渡すときのみ、第二引数に true を添える(モードスイッチ)。

他は特に説明要らないと思う。

Function doCmdSh( _
        ByVal cmdStr As String, _
        Optional ByVal pwrsw As Boolean = False _
    ) As String
    Dim Wsh: Set Wsh = CreateObject("Wscript.shell")
    Dim Fso: Set Fso = CreateObject("Scripting.FileSystemObject")
    Dim tempPath As String: tempPath = Environ$("temp") & "\" & Fso.GetTempName: Fso.CreateTextFile (tempPath)
    Dim cmdBody
    If Not pwrsw Then
        cmdBody = "cmd.exe /c " & cmdStr & " > " & tempPath
    Else
        cmdBody = "powershell -ExecutionPolicy RemoteSigned -Command Invoke-Expression """
        cmdBody = cmdBody & cmdStr & " | Out-File -filePath " & tempPath & " -encoding Default"""
    End If

    Wsh.Run cmdBody, 0, True ' WshHide = 0
    
    Dim result As String
    Dim strm As Object: Set strm = Fso.OpenTextFile(tempPath, 1) ' ForReading = 1
    result = strm.ReadAll
    strm.Close
    Call Fso.DeleteFile(tempPath, True)
    doCmdSh = result
End Function

Function doCmdShAsArray(cmdString As String, Optional ByVal pwrsw As Boolean = False) As String()
    doPwrShAsArray = Split(doPwrSh(cmdString, pwrsw), vbNewLine)
End Function

2017/08/20 22:22 追記
doCmdSh で awk 呼ぶのも良いかも。