LoginSignup
2

More than 3 years have passed since last update.

【VBA】エクセルでbatファイル実行

Last updated at Posted at 2019-11-14
command
./test.bat aaa
test.bat(%1=aaa)
powershell -NoLogo -ExecutionPolicy RemoteSigned -Command .\test.ps1 %1
test.ps1($Args[0]=%1=aaa)
#中間テキストファイル指定
[System.String]$textLog = './test.txt'
#検索文字列指定
[System.String]$findstring = 'abc'

do {
    $loopflag = $False    #ループ初期化(無効)
    #$Args[0] = 引数[1]
    #command $Args[0] $Args[1]
    $Output = $Args[0]  #test command

    #中間テキストファイル出力
    #command             | tee-object -file test.txt
    Write-Output $Output | tee-object -file test.txt

    #文字列があるか検索
    $textChk = @(Get-Content $textLog -TotalCount 2)[-1] | Select-String -SimpleMatch $findstring -quiet

    #結果がTrueであれば再度実行
    if ($textChk -eq $True) {
        $loopflag = $True    #ループ有効
    }

    #中間テキストファイル削除
    #Remove-Item './test.txt'
} while ($loopflag)


バッチだけに作り直し

test.bat
@echo off

@rem テキストファイル名指定
set txtFile=.\batlog.txt
set findString=aiue

@rem cygwinのteeコマンドを利用
@rem [command] [引数(%1)] 2>&1 | C:\cygwin64\bin\tee.exe %txtFile%
echo %1 2>&1 | C:\cygwin64\bin\tee.exe %txtFile%

:loop
    findstr %findString% %txtFile% > NUL
    if "%ERRORLEVEL%"=="0" (
        @rem 文字列があればループ終了
        echo "検索あり"
        goto :end
    ) else if "%ERRORLEVEL%"=="1" (
        @rem 文字列がなければ再実行
        echo "検索なし"
        goto :loop
    )
:end

@rem テキストファイル削除
rm -f txtFile


VBAでバッチ実行

標準モジュール
Sub RunBatWshShell()
    Dim obj As WshShell
    Dim fPath
    Dim sPath
    Dim sParam1
    Dim sParam2
    Dim tName
    Dim tPathName
    Dim sCheck
    Dim fLoop
    Dim buf

    Set obj = New WshShell

    'loop確認文字列
    sCheck = "abc"

    '引数取得
    sParam1 = Range("B3")
    sParam2 = Range("C3")

    'パス取得
    fPath = ThisWorkbook.Path
    sPath = fPath & "\" & "test.bat" & " " & fPath & " " & sParam1 & " " & sParam2
    s2Path = fPath & "\" & "test2.bat"

    '結果テキストファイル名
    tName = "test.txt"
    tPathName = fPath & "\" & tName

    'Loop flag初期化(有効)
    fLoop = True
    Do While fLoop
        'Loop flag初期化(無効)
        fLoop = False

        'bat実行
        Call obj.Run(sPath, WaitOnReturn:=True)

        With CreateObject("ADODB.Stream")
            .Charset = "UTF-16"
            .Open
            .LoadFromFile tPathName
            buf = .ReadText
            .Close
        End With
        If InStr(buf, sCheck) <> 0 Then
            'ループを有効
            fLoop = True
        End If

        Call obj.Run(s2Path, WaitOnReturn:=True)
    Loop
End Sub


標準モジュール(simple)
Sub RunBatWshShell()
    Dim obj As WshShell
    Set obj = New WshShell

    'batファイル名
    batName = Range("B1")

    '引数取得
    sParam1 = Range("B3")
    sParam2 = Range("C3")

    'パス取得
    fPath = ThisWorkbook.Path
    sPath = fPath & "\" & batName & " " & fPath & " " & sParam1 & " " & sParam2

    'bat実行
    Call obj.Run(sPath, WaitOnReturn:=True)
End Sub

image.png

testVB
@echo off

@rem テキストファイル名指定
set txtFile=%1\batlog.txt
set findString=aiue

@rem cygwinのteeコマンドを利用
@rem [command] [引数(%1)] 2>&1 | C:\cygwin64\bin\tee.exe %txtFile%
echo %2 %3 2>&1 | C:\cygwin64\bin\tee.exe %txtFile%

:loop
    findstr %findString% %txtFile% > NUL
    if "%ERRORLEVEL%"=="0" (
        @rem 文字列があればループ終了
        echo "検索あり"
        goto :end
    ) else if "%ERRORLEVEL%"=="1" (
        @rem 文字列がなければ再実行
        echo "検索なし"
        @rem goto :loop
    )
:end

@rem コマンドが終わっても画面を閉じない
cmd /k

@rem テキストファイル削除
rm -f txtFile


参考
Powershellを楽に実行してもらうには - Qiita
PowerShellのGet-Contentでハマったところ - Qiita
Windowsバッチファイル(.bat)、処理が終わった後にウィンドウを閉じない|マコトのおもちゃ箱 ~ぼへぼへ自営業者の技術メモ~
PowerShellでファイルから文字検索チェック - 社内SEの徒然なる日記
Powershellで引数を受け取る | マイクロソフ党ブログ
PowerShellスクリプティングの第一歩(後編) (2/5):Windows PowerShellコマンド&スクリプティング入門 - @IT
【PowerShell】繰り返し文(While, For)について | SEブログ
入力を2箇所に出力する(tee-object) - PowerShell Memo


参考
PowerShell/テキストファイルを1行ずつ読み込むサンプルコード - Windowsと暮らす
テキストファイルの読み込み、書き込み
VBAで他のアプリケーションを同期起動する(WshShell) | Excel作業をVBAで効率化
VBAでバッチファイル(bat)を実行する | Excel作業をVBAで効率化
バッチファイル(.bat)からパワーシェルファイル(.ps1)を実行する方法[PowerShell] : バヤシタ

Windowsで標準出力とファイルの両方へ出力している風に見せる - しもむブログ
コマンドプロンプト - Windows のコマンドプロンプトで、画面出力した上で、ログにも出力したい - スタック・オーバーフロー
コマンドの実行結果をファイルに出力する - Windows - Project Group
[Windows]バッチファイルで任意の文字列を入力させる | ごった煮 - tips about programming and building a server
【ExcelVBA入門】カレントディレクトリの取得・変更方法を徹底解説! | 侍エンジニア塾ブログ(Samurai Blog) - プログラミング入門者向けサイト
【VBA入門】OpenメソッドでテキストファイルやCSVの読み込み | 侍エンジニア塾ブログ(Samurai Blog) - プログラミング入門者向けサイト

標準出力 (stdout) と標準エラー (stderr) への出力をファイルに保存する | まくまくWindowsノート
コマンド プロンプトからのエラー メッセージをリダイレクトする: 標準エラー出力と標準出力
バッチファイルで変数を使う
Windowsのコマンドプロンプトでファイルを1行ずつ読み込む - Qiita
コマンドプロンプト findstr - [文字列や正規表現を使って文字列を検索する]

batファイルでコマンドの実行結果を出力しないようにする方法 - Qiita
findstrコマンドで検索した結果を条件分岐に用いる - とりあえず半歩
teeコマンドの使い方 - Qiita
バッチファイルでループ処理する

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
2