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

```:command
./test.bat aaa
```

```bash:test.bat(%1=aaa)
powershell -NoLogo -ExecutionPolicy RemoteSigned -Command .\test.ps1 %1
```

```bash: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)

```
---

バッチだけに作り直し

```bash: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でバッチ実行

```vb:標準モジュール
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

```

----

```vb:標準モジュール(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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506079/b73069c2-6730-0cb7-7dd0-4d69fa9e867e.png)


```bash: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](https://qiita.com/tomoko523/items/df8e384d32a377381ef9)
[PowerShellのGet-Contentでハマったところ - Qiita](https://qiita.com/noonworks/items/6cffb09d0df12403fe72)
[Windowsバッチファイル（.bat）、処理が終わった後にウィンドウを閉じない｜マコトのおもちゃ箱　～ぼへぼへ自営業者の技術メモ～](http://piyopiyocs.blog115.fc2.com/blog-entry-1039.html)
[PowerShellでファイルから文字検索チェック - 社内SEの徒然なる日記](http://harikofu.blog.fc2.com/blog-entry-970.html?sp)
[Powershellで引数を受け取る | マイクロソフ党ブログ](https://microsoftou.com/ps-arguments/)
[PowerShellスクリプティングの第一歩（後編） (2/5)：Windows PowerShellコマンド＆スクリプティング入門 - ＠IT](https://www.atmarkit.co.jp/ait/articles/0709/20/news125_2.html)
[【PowerShell】繰り返し文(While, For)について | SEブログ](https://soma-engineering.com/coding/powershell/loop-while-for/2018/06/09/#do-while)
[入力を２箇所に出力する(tee-object) - PowerShell Memo](https://newpops.hatenadiary.org/entry/20051027/p1)

---
>参考
[PowerShell/テキストファイルを１行ずつ読み込むサンプルコード - Windowsと暮らす](https://win.just4fun.biz/?PowerShell/%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%EF%BC%91%E8%A1%8C%E3%81%9A%E3%81%A4%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%80%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89#l0c1f324)
[テキストファイルの読み込み、書き込み](http://suyamasoft.blue.coocan.jp/PowerShell/Tips/TextFile/Get-Content/index.html#Encoding)
[VBAで他のアプリケーションを同期起動する（WshShell） ｜ Excel作業をVBAで効率化](https://vbabeginner.net/vba%e3%81%a7%e4%bb%96%e3%81%ae%e3%82%a2%e3%83%97%e3%83%aa%e3%82%b1%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3%e3%82%92%e5%90%8c%e6%9c%9f%e8%b5%b7%e5%8b%95%e3%81%99%e3%82%8b%ef%bc%88wshshell%ef%bc%89/)
[VBAでバッチファイル（bat）を実行する ｜ Excel作業をVBAで効率化](https://vbabeginner.net/vba%E3%81%A7%E3%83%90%E3%83%83%E3%83%81%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%EF%BC%88bat%EF%BC%89%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B/)
[バッチファイル（*.bat）からパワーシェルファイル（*.ps1）を実行する方法[PowerShell] : バヤシタ](https://bayashita.com/p/entry/show/106)
>
[Windowsで標準出力とファイルの両方へ出力している風に見せる - しもむブログ](http://mshimomu.hatenablog.jp/entry/2015/09/06/012702)
[コマンドプロンプト - Windows のコマンドプロンプトで、画面出力した上で、ログにも出力したい - スタック・オーバーフロー](https://ja.stackoverflow.com/questions/30142/windows-%E3%81%AE%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%83%97%E3%83%AD%E3%83%B3%E3%83%97%E3%83%88%E3%81%A7-%E7%94%BB%E9%9D%A2%E5%87%BA%E5%8A%9B%E3%81%97%E3%81%9F%E4%B8%8A%E3%81%A7-%E3%83%AD%E3%82%B0%E3%81%AB%E3%82%82%E5%87%BA%E5%8A%9B%E3%81%97%E3%81%9F%E3%81%84)
[コマンドの実行結果をファイルに出力する - Windows - Project Group](https://www.projectgroup.info/tips/Windows/cmd_0002.html)
[[Windows]バッチファイルで任意の文字列を入力させる | ごった煮 - tips about programming and building a server](http://park1.wakwak.com/~ima/windows_tips0004.html)
[【ExcelVBA入門】カレントディレクトリの取得・変更方法を徹底解説！ | 侍エンジニア塾ブログ（Samurai Blog） - プログラミング入門者向けサイト](https://www.sejuku.net/blog/74911)
[【VBA入門】OpenメソッドでテキストファイルやCSVの読み込み | 侍エンジニア塾ブログ（Samurai Blog） - プログラミング入門者向けサイト](https://www.sejuku.net/blog/34458#i-11)
>
[標準出力 (stdout) と標準エラー (stderr) への出力をファイルに保存する | まくまくWindowsノート](https://maku77.github.io/windows/io/redirect-stdout-and-stderr.html)
[コマンド プロンプトからのエラー メッセージをリダイレクトする: 標準エラー出力と標準出力](https://support.microsoft.com/ja-jp/help/110930/redirecting-error-messages-from-command-prompt-stderr-stdout)
[バッチファイルで変数を使う](https://jj-blues.com/cms/wantto-variableinbatfile/)
[Windowsのコマンドプロンプトでファイルを1行ずつ読み込む - Qiita](https://qiita.com/Nemy/items/1169aee51473a09aed41)
[コマンドプロンプト findstr - [文字列や正規表現を使って文字列を検索する]](https://www.k-tanaka.net/cmd/findstr.php)
>
[batファイルでコマンドの実行結果を出力しないようにする方法 - Qiita](https://qiita.com/uhooi/items/b8b25761a5c4efe9025a)
[findstrコマンドで検索した結果を条件分岐に用いる - とりあえず半歩](http://sotoattanito.hatenablog.com/entry/2015/10/21/232557)
[teeコマンドの使い方 - Qiita](https://qiita.com/wnoguchi/items/2fc3ec11043d139dc6bb)
[バッチファイルでループ処理する](https://jj-blues.com/cms/wantto-useloop/)