2017年6月4日

【Excel】ファイルの存在確認をするマクロ(PowerShellのTest-Pathを使った方法)


VBAでPowerShellのTest-Pathを使ってファイルの存在確認が出来るか試してみました。


WScript.ShellのExecメソッド

Execメソッドを使うと標準入力、標準出力、標準エラー出力を利用することが出来きますので、これを使ってファイルの存在判定を行います。
Sub CheckFile3()

    Dim filePath As String
    Dim oShell As Object
    
    Set oShell = CreateObject("WScript.Shell")

    Dim oExec As Object
    Dim oOutput As Object
    
    filePath = "C:\work\Excel\output.txt"
    
    'Execメソッド
    Set oExec = oShell.Exec("powershell -WindowStyle Hidden -command Test-Path """ & filePath & """")

    '標準出力の値を取得    
    Set oOutput = oExec.StdOut

    Dim bufStr As String
    
    While Not oOutput.AtEndOfStream

        '取得した値から1行読みとる
        bufStr = oOutput.ReadLine
        
        If bufStr = "True" Then
            MsgBox filePath & " は存在します。"
        Else
            MsgBox filePath & " は存在しません。"
        End If
    Wend

End Sub
Execメソッドでpowershellを起動するときに「-WindowStyle Hidden」を使って、ウィンドウを非表示設定にしてますが、一瞬だけプロンプト画面が表示されてしまいます。この一瞬だけチラって見えるのがカッコ悪くてなんとかならないかといろいろ調べましたが、どうやら無理なようです。

まあ、ちょっとぐらいプロンプトが表示されても気にならないという方は、この方法でいいと思います。

ただ、チラっとか見えるの嫌だ!、という方は次の方法を試してみてください。
ShellのRunメソッドを使って完全非表示にしています。


WScript.ShellのRunメソッド

Runメソッドを使うとプロンプトを非表示にすることが出来ます。
ただ、この方法ですと標準出力の値は取得できませんのでTest-Pathの結果を知る方法が別に必要です。
今回は手っ取り早くクリップボードを使って結果を取得するようにしてみました。
Sub CheckFile4()

    Dim filePath As String
    Dim ret As Long
    Dim ClipBoard As Variant
    Dim cb As New DataObject
    Dim cbText As String
    
    filePath = "C:\work\Excel\output.txt"
    
    Dim cmd As String
    cmd = "powershell Test-Path """ & filePath & """ | Set-Clipboard "
    
    With CreateObject("Wscript.Shell")
        ret = .Run(cmd, 0, True)
    End With

    'クリップボードの値を取得    
    cb.GetFromClipboard
    cbText = cb.GetText
    
    If cbText = "True" Then
        MsgBox filePath & " は存在します。"
    Else
        MsgBox filePath & " は存在しません。"
    End If
    
End Sub
Test-Pathの結果は、パイプラインを使ってSet-Clipboardでクリップボードに格納しています。

ちなみに、DataObjectオブジェクトを使用するには、参照設定で「Microsoft Forms 2.0 Object Library」にチェックを入れる必要があります。


もし、参照設定に「Microsoft Forms 2.0 Object Library」が出てこない場合は、[参照]ボタンから「c:\Windows\System32\FM20.DLL」または「C:\Windows\SysWOW64\FM20.DLL」を追加してください。


今回、試しにPowerShellのTest-Pathを使った方法を考えてみましたが、普通にFileSystemObjectとかを使ったほうがはるかに簡単です。まあでも、PowerShellのコマンドレットを利用したいといったこともあると思いますので、そういったときに今回のやり方が使えそうな気がします。



スポンサーリンク