Update:2017/04/28-01:39:00
バッチで処理を作っていると、ちょっとした文字列の操作やYes/Noなどの処理選択が欲しい時があります。
そんな時に、便利に使えるのがVBscriptですが、意外とパラメータの受け渡しで手間取ることが多いものです。
ここでは、BATとVBscriptのインターフェースをパターン化して手軽にVBscriptを使えるようにしてみます。
方針は、バッチからのVBscript呼び出しには「FORコマンド」を使い、VBscriptからの戻り値(リターン値)を文字列で受け取るようにします。
BATからのVBscript呼び出しパターン)
FOR /F "usebackq tokens=* delims=" %%S IN (`CALL cscript //NoLogo VBscript名 "%par%"`) DO SET ret=%%S
VBscript側では、バッチから文字列として引数を受け取り、処理結果も文字列として、標準出力へ出力します。
VBscriptのテンプレート)
REM --------------------ここから
Option Explicit
REM ----+----1----+----2----+----3
REM 説明文を入れておきます。
REM ----+----1----+----2----+----3
Dim args, arg(99), v, cnt
Dim str1, str2
Dim mode
Dim respond, eLevel
Dim CRLF
REM 改行符号を設定します。
CRLF = chr(13) & chr(10)
REM 引数の設定
Set args = WScript.Arguments
cnt = 1
For Each v In args
arg(cnt) = v
cnt = cnt + 1
Next
eLevel = 0: REM エラーが発生したときに値を設定します。
respond = "": REM 呼び出し元への戻り値を設定します。
REM --------------------------------
↑
ここに処理を記述します。
↓
REM --------------------------------
REM 結果の表示
WScript.Echo respond
WScript.Quit (eLevel)
REM --------------------ここまで
VBSからの戻り値(リターン値)を複数渡したい場合は、文字列をスペースなどで区切って使うようにします。(配列で渡したいときは、「VBScriptの戻り値を配列で受け取る」を参照してください。)
また、VBscriptは、なるべく小さな単機能のスクリプトのほうが使い勝手が良いと思います。
極端な話、VBscriptの命令や関数1つづつを外部コマンドのようにサブルーチン化すると良いでしょう。
このサンプルでは、BATファイルとVBscriptは同じディレクトリ内に置いてあるものとします。
実際には、VBscriptは、BATファイルの置いてあるディレクトリの下にサブディレクトリを(vbsなどの名前で)作成しこの中に配置しておくほうが扱いやすいと思います。
BAT側 [strlen.bat]
REM 文字列の長さを求める
SET str=%date%-%time%
SET mode=1
for /f "usebackq tokens=*
delims=" %%D in (`call cscript //Nologo strlen.vbs "%str%" %mode%`)
do SET res=%%D
echo %res%
pause
exit /b
VBscript側 [strlen.vbs]
Option Explicit
REM ------------------------------------------------------
REM strlen.vbs str [,mode]
REM str:対象となる文字列
REM mode:0→文字数で表示, 1→バイト数で表示
REM (動作)
REM str に含まれる文字の長さを返します。
REM ------------------------------------------------------
Dim args, arg(99), v, cnt
Dim str
Dim mode
Dim respond, eLevel
Dim CRLF
REM 改行符号を設定します。
CRLF = chr(13) & chr(10)
Set args = WScript.Arguments
cnt = 1
For Each v In args
arg(cnt) = v
cnt = cnt + 1
Next
If 1 =< args.Count Then
str = arg(1)
If 1 = arg(2) Then
mode = 1
respond
= LenB (str)
Else
mode = 0
respond
= Len (str)
End If
eLevel = 0
Else
respond = "-1"
eLevel = 1
End If
REM 結果の表示
WScript.Echo Ltrim (respond)
WScript.Quit (eLevel)
BAT側 [strpos.bat]
REM 文字列の位置を検査
SET str=%date%-%time%
SET ptn=/
for /f "usebackq tokens=*
delims=" %%D in (`call cscript //Nologo strpos.vbs "%str%" "%ptn%"`)
do SET res=%%D
echo %res%
pause
exit /b
VBscript側 [strpos.vbs]
Option Explicit
REM ------------------------------------------------------
REM strpos.vbs str1 , str2 [,mode]
REM str1:検索対象となる文字列
REM str2:検索する文字列
REM mode:0→文字位置で表示, 1→バイト位置で表示
REM (動作)
REM str1 の中から str2 を検索し、最初に見つかった文字位置
REM を返します。
REM ------------------------------------------------------
Dim args, v, arg(99), cnt
Dim str1, str2
Dim mode
Dim respond, eLevel
Dim CRLF
CRLF = chr(13) & chr(10)
Set args = WScript.Arguments
cnt = 1
For Each v In args
arg(cnt) = v
cnt = cnt + 1
Next
If 2 =< args.Count Then
str1 = arg(1)
str2 = arg(2)
mode = 0
If 1 = arg(3) Then
mode = 1
respond
= InstrB (str1, str2)
Else
respond
= Instr (str1, str2)
End If
eLevel = 0
Else
respond = ""
eLevel = 1
End If
REM 結果の表示
WScript.Echo Ltrim (respond)
WScript.Quit (eLevel)
BAT側 [substr.bat]
REM 文字列の抽出
SET str=%date%-%time%
SET pos=8
SET len=2
for /f "usebackq tokens=* delims=" %%D in (`call cscript //Nologo vbs\mid.vbs "%str%" "%pos%" "%len%"`) do SET res=%%D
echo %res%
pause
exit /b
VBscript側 [substr.vbs]
Option Explicit
REM ------------------------------------------------------
REM substr.vbs str , pos [,leng] [, mode]
REM str:取り出し対象の文字列
REM pos:取り出し開始位置
REM leng:取り出す文字の長さ
REM mode:0→文字位置で表示, 1→バイト位置で表示
REM (動作)
REM 文字列 str 中の pos で指定される位置から leng の長さ
REM だけ文字を取り出します。
REM ------------------------------------------------------
Dim args, arg(99), v, cnt
Dim str, pos, leng
Dim mode
Dim respond, eLevel
Dim CRLF
CRLF = chr(13) & chr(10)
Set args = WScript.Arguments
cnt = 1
For Each v In args
arg(cnt) = v
cnt = cnt + 1
Next
If 2 =< args.Count Then
str = arg(1)
pos = arg(2)
If 2 < args.Count Then
leng = arg(3)
If 4 = args.Count Then
mode = arg(4)
Else
mode = 0
End If
If mode Then
respond = MidB (str, pos, leng)
Else
respond = Mid (str, pos, leng)
End If
Else
respond = Mid (str, pos)
End If
eLevel = 0
Else
respond = ""
eLevel = 1
End If
REM 結果の表示
WScript.Echo respond
WScript.Quit (eLevel)
BAT側 [regexp.bat]
@ECHO OFF
TITLE 文字列検索
SET chk=%~1
SET sw=%1%
IF "%chk%" == "" SET /P chk=検索文字列:
IF "%chk:~0,3%" == "/f:" SET sw=%chk%
IF "%chk:~0,3%" == "/F:" SET sw=%chk%
IF "%chk:~0,3%" == "/s:" SET sw=%chk:~3%
IF "%chk:~0,3%" == "/S:" SET sw=%chk:~3%
IF "%sw%" == "" GOTO MSG
SET t=%~2
IF "%~2" == "" SET /P t=入力ファイル名:
IF "%~3" == "" GOTO THEN01
cscript //Nologo regexp.vbs %sw%
< %t% > %3
GOTO END_IF
:THEN01
IF "%t%" == "" GOTO THEN02
cscript //Nologo regexp.vbs %sw%
< %t%
DEL "%t%" & REN "%t%.bak" %~nx2
GOTO END_IF
:THEN02
cscript //Nologo regexp.vbs %sw%
:END_IF
ECHO ON
@EXIT /B
:MSG
ECHO 使い方
ECHO %~nx0 "検索パターン" 入力ファイル名 [出力ファイル名]
ECHO 検索パターンには、正規表現が使えます。
ECHO (例)
ECHO . 任意の1文字
ECHO \r 復帰
ECHO \n 改行
ECHO \w 英数字または「_」
ECHO \W 英数字または「_」でない文字
ECHO \s スペース、タブ、改行などの空白文字
ECHO \Sスペース、タブ、改行など空白文字でない文字
ECHO \d 数字
ECHO \D 数字でない文字
ECHO \\ \記号
ECHO \x16進数 2桁の16進数での文字コードによる文字指定
ECHO [文字リスト] 文字リスト中の1文字
ECHO [^文字リスト] 文字リストに含まれない文字
ECHO ^ 行頭
ECHO $ 行末
ECHO ? 直前の文字パターンが0回または1回出現
ECHO * 直前の文字パターンが0回以上出現
ECHO + 直前の文字パターンが1回以上出現
ECHO {m,n} 直前の文字パターンがm回以上、n回以下出現
ECHO (文字列1 ^| 文字列2) 文字列1または文字列2
PAUSE
ECHO ON
@EXIT /B
VBscript側 [regexp.vbs]
Option Explicit
REM ------------------------------------------------------
REM regExp.vbs str1 , str2 [,mode]
REM str1:検索対象の文字列
REM str2:検索パターン
REM mode:動作モードを指定します。
REM (動作)
REM 正規表現による文字列の検索や置換を行います。
REM 検索/置換結果は、コンマ区切りの文字列で返されます。
REM ------------------------------------------------------
Dim args, arg(99), v, cnt
Dim str1, str2, ptn, replacing
Dim mode, delim
Dim sw_o, sw_x, chg
Dim matches(999), str
Dim respond, eLevel
Dim CRLF
REM 改行符号を設定します。
CRLF = chr(13) & chr(10)
Set args = WScript.Arguments
cnt = 1
For Each v In args
arg(cnt) = v
cnt = cnt + 1
Next
eLevel = 0: REM エラーが発生したときに値を設定します。
respond = "": REM 呼び出し元への戻り値を設定します。
REM --------------------------------
REM 検索対象の文字列
str1=arg(1)
REM 検索パターンの文字列
str2=arg(2)
msgbox str1 & CRLF & str2 & arg(3)
delim=left(str2, 1)
ptn=Split(str2, delim, -1)
cnt = 0
for each v in ptn
respond=respond & CRLF
& cnt & ":" & v
cnt = cnt + 1
next
If "" < ptn(2) Then replacing=1 Else replacing=0
REM 検索の動作指定
mode=lcase(arg(3))
sw_o=0
If instr(mode, "/i") Then sw_o=1
If instr(mode, "/g") Then sw_o=2
REM If instr(mode, "/e") Then sw_o=4
REM 検索結果の区切り符合を指定(既定は「 」:半角スペース)
chg = " "
If instr(mode, "/x:") Then
chg = mid(mode, instr(mode, "/x:") + 3,
1)
End If
If 0 = replacing Then
str = ""
Select Case sw_o
Case 0:
Set list = RegExG (str1, ptn(1))
cnt = 0
For Each v In list
matches(cnt) = v
cnt = cnt + 1
Next
str = matches(0)
Case 1:
Set list = iRegExG (str1, ptn(1))
cnt = 0
For Each v In list
matches(cnt) = v
cnt = cnt + 1
Next
str = matches(0)
Case 2:
Set list = RegExG (str1, ptn(1))
cnt = 0
For Each v In list
str = str & chg & v
cnt = cnt + 1
Next
Case 3:
Set list = iRegExG (str1, ptn(1))
cnt = 0
For Each v In list
str = str & chg & v
cnt = cnt + 1
Next
Case 4:
Set list = RegExG (str1, ptn(1))
cnt = 0
For Each v In list
matches(cnt) = v
cnt = cnt + 1
Next
str = matches(0)
Case 5:
Set list = iRegExG (str1, ptn(1))
cnt = 0
For Each v In list
matches(cnt) = v
cnt = cnt + 1
Next
str = matches(0)
Case 6:
Set list = RegExG (str1, ptn(1))
cnt = 0
For Each v In list
str = str & chg & v
cnt = cnt + 1
Next
Case 7:
Set list = iRegExG (str1, ptn(1))
cnt = 0
For Each v In list
str = str & chg & v
cnt = cnt + 1
Next
End Select
Else
str = ""
Select Case sw_o
Case 0:
str = RepEx (str1, ptn(1), ptn(2))
Case 1:
str = iRepEx (str1, ptn(1), ptn(2))
Case 2:
str = RepExG (str1, ptn(1), ptn(2))
Case 3:
str = iRegExG (str1, ptn(1), ptn(2))
Case 4:
str = RegExG (str1, ptn(1), ptn(2))
Case 5:
str = iRegExG (str1, ptn(1), ptn(2))
Case 6:
str = RegExG (str1, ptn(1), ptn(2))
Case 7:
str = iRegExG (str1, ptn(1), ptn(2))
End Select
End If
respond = str
REM --------------------------------
REM 結果の表示
WScript.Echo respond
WScript.Quit (eLevel)
'ここからサブルーチン=====================================================
' 原稿文字列を正規文字列で検索し、一致する文字をオブジェクトとして取り出します。
' ローマ字の大文字小文字を区別します。
' regSource : 原稿文字列
' regPattern : 正規文字列
Function RegExG ( regSource , regPattern )
Dim regExpression,
Matches ' 変数を作成します。
Set regExpression = New
RegExp ' 正規表現を作成します。
regExpression.Pattern =
regPattern ' パターンを設定します。
regExpression.IgnoreCase =
False ' 大文字と小文字を区別するように設定します。
regExpression.Global =
True ' 文字列全体を検索するように設定します。
Set Matches =
regExpression.Execute(regSource) ' 検索を実行します。
Set RegExG = Matches
End Function
' 原稿文字列を正規文字列で検索し、一致する文字をオブジェクトとして取り出します。
' ローマ字の大文字小文字を区別しません。
' regSource : 原稿文字列
' regPattern : 正規文字列
Function iRegExG ( regSource , regPattern )
Dim regExpression,
Matches ' 変数を作成します。
Set regExpression = New
RegExp ' 正規表現を作成します。
regExpression.Pattern =
regPattern ' パターンを設定します。
regExpression.IgnoreCase =
True ' 大文字と小文字を区別しないように設定します。
regExpression.Global =
True ' 文字列全体を検索するように設定します。
Set Matches =
regExpression.Execute(regSource) ' 検索を実行します。
Set iRegExG = Matches
End Function
'---------------------------------------------------------------------
' 原稿文字列を正規文字列で検索し、一致する文字をすべて置換文字列に置き換えます。
' regSource : 原稿文字列
' regPattern : 正規文字列
' regTarget : 置換文字列
Function iRepExAll ( regSource , regPattern , regTarget )
Dim regExpression,
Matches ' 変数を作成します。
Set regExpression = New
RegExp ' 正規表現を作成します。
regExpression.Pattern =
regPattern ' パターンを設定します。
regExpression.IgnoreCase =
True ' 大文字と小文字を区別しないように設定します。
regExpression.Global =
True ' 文字列全体を検索するように設定します。
iRepExAll =
regExpression.Replace(regSource , regTarget) '
置換を実行します。
End Function
Function iRepExG ( regSource, regPattern, regTarget )
Dim regExpression,
Matches ' 変数を作成します。
Set regExpression = New
RegExp ' 正規表現を作成します。
regExpression.Pattern =
regPattern ' パターンを設定します。
regExpression.IgnoreCase =
True ' 大文字と小文字を区別しないように設定します。
regExpression.Global =
True ' 見つかったすべての文字列を置換するように設定します。
iRepExG =
regExpression.Replace(regSource , regTarget) '
置換を実行します。
End Function
' 原稿文字列を正規文字列で検索し、一致する文字を置換文字列に置き換えます。
' ローマ字の大文字小文字を区別しません。
' regSource : 原稿文字列
' regPattern : 正規文字列
' regTarget : 置換文字列
Function iRepEx ( regSource , regPattern , regTarget )
Dim regExpression,
Matches ' 変数を作成します。
Set regExpression = New
RegExp ' 正規表現を作成します。
regExpression.Pattern =
regPattern ' パターンを設定します。
regExpression.IgnoreCase =
True ' 大文字と小文字を区別しないように設定します。
regExpression.Global =
False ' 最初に見つかった文字列のみ置換するように設定します。
iRepEx = regExpression.Replace(regSource
, regTarget) ' 置換を実行します。
End Function
' 原稿文字列を正規文字列で検索し、一致する文字を置換文字列に置き換えます。
' ローマ字の大文字小文字を区別します。
' regSource : 原稿文字列
' regPattern : 正規文字列
' regTarget : 置換文字列
Function RepEx ( regSource , regPattern , regTarget )
Dim regExpression,
Matches ' 変数を作成します。
Set regExpression = New
RegExp ' 正規表現を作成します。
regExpression.Pattern =
regPattern ' パターンを設定します。
regExpression.IgnoreCase =
False ' 大文字と小文字を区別するように設定します。
regExpression.Global =
False ' 最初に見つかった文字列のみ置換するように設定します。
RepEx = regExpression.Replace(regSource
, regTarget) ' 置換を実行します。
End Function
Function RepExG ( regSource , regPattern , regTarget )
Dim regExpression,
Matches ' 変数を作成します。
Set regExpression = New
RegExp ' 正規表現を作成します。
regExpression.Pattern =
regPattern ' パターンを設定します。
regExpression.IgnoreCase =
False ' 大文字と小文字を区別するように設定します。
regExpression.Global =
True ' 見つかったすべての文字列を置換するように設定します。
RepExG = regExpression.Replace(regSource
, regTarget) ' 置換を実行します。
End Function
BAT側 [msgbox.bat]
REM メッセージボックスの表示
SET str="メッセージボックスのテスト「CRLF」で改行します。"
SET btn=67
SET tm=%date%-%time%
echo %str%
echo %btn%
for /f "usebackq tokens=*
delims=" %%D in (`call cscript //Nologo msgbox.vbs %str% "%btn%"`) do SET res=%%D
echo %res%
pause
exit /b
VBscript側 [msgbox.vbs]
Option Explicit
REM ------------------------------------------------------
REM msgbox.vbs str1 , str2 [,mode]
REM str1:表示するメッセージ
REM num :表示するボタンの選択
REM str2:メッセージボックスのタイトル
REM (動作)
REM メッセージボックスを表示し、クリックされたボタンを
REM 返します。
REM str1 中の 「crlf」という文字列は改行に変換します。
REM ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
REM ボタンの表示選択と動作などの設定(ボタン表示や動作などの値を合計します。)
REM 0 [OK] ボタンのみを表示します。
REM 1 [OK] ボタンと [キャンセル]
ボタンを表示します。
REM 2 [中止]、[再試行]、および [無視] の 3
つのボタンを表示します。
REM 3 [はい]、[いいえ]、および [キャンセル] の
3 つのボタンを表示します。
REM 4 [はい] ボタンと [いいえ]
ボタンを表示します。
REM 5 [再試行] ボタンと [キャンセル]
ボタンを表示します。
REM 16 警告メッセージ アイコンを表示します。
REM 32 問い合わせメッセージ アイコンを表示します。
REM 48 注意メッセージ アイコンを表示します。
REM 64 情報メッセージ アイコンを表示します。
REM 0 第 1 ボタンを標準ボタンにします。
REM 256 第 2 ボタンを標準ボタンにします。
REM 512 第 3 ボタンを標準ボタンにします。
REM 768 第 4 ボタンを標準ボタンにします。
REM 0 アプリケーション モーダルに設定します。メッセージ
ボックスに応答するまで、現在選択中のアプリケーションの実行を継続できません。
REM 4096 システム モーダルに設定します。メッセージ
ボックスに応答するまで、すべてのアプリケーションが中断されます。
REM ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
REM 戻り値となる文字列
REM ボタンの名前
-> respondの戻り値
REM [OK]
-> Ok
REM [キャンセル]
-> Cancel
REM [中止]
-> Stop
REM [再試行]
-> Retry
REM [無視]
-> Ignore
REM [はい]
-> Yes
REM [いいえ]
-> No
REM ------------------------------------------------------
Dim args, arg(99), v, cnt
Dim str1, str2
Dim mode
Dim respond, eLevel
Dim CRLF
REM 改行符号を設定します。
CRLF = chr(13) & chr(10)
Set args = WScript.Arguments
cnt = 1
For Each v In args
arg(cnt) = v
cnt = cnt + 1
Next
REM 改行文字の置き換え
arg(1) = RepExAll (arg(1), "crlf", CRLF)
eLevel = 0
Select Case args.Count
Case 0: mode = 0: eLevel = 1
Case 1: mode = MsgBox (arg(1))
Case 2: mode = MsgBox (arg(1), arg(2))
Case Else: mode = MsgBox (arg(1),
arg(2), arg(3))
End Select
Select Case mode
Case 0: respond = ""
Case 1: respond = "Ok"
Case 2: respond = "Cancel"
Case 3: respond = "Stop"
Case 4: respond = "Retry"
Case 5: respond = "Ignore"
Case 6: respond = "Yes"
Case 7: respond = "No"
End Select
REM 結果の表示
WScript.Echo respond
WScript.Quit (eLevel)
REM ここからサブルーチン=========================================
REM 原稿文字列を正規文字列で検索し、一致する文字をすべて置換文字列に置き換えます。
REM s : 原文字列
REM t : 正規文字列
REM d : 置換文字列
Function RepExAll ( s , t , d )
Dim regExpression,
Matches ' 変数を作成します。
Set regExpression = New
RegExp ' 正規表現を作成します。
regExpression.Pattern =
t ' パターンを設定します。
regExpression.IgnoreCase =
True ' 大文字と小文字を区別しないように設定します。
regExpression.Global =
True ' 文字列全体を検索するように設定します。
RepExAll = regExpression.Replace(s ,
d) ' 置換を実行します。
End Function
BAT側 [inputbox.bat]
REM 文字列の入力ボックスを表示
SET str1="日付/時刻をcrlf入力します。"
SET str2="インプットボックスのテスト"
SET str3=%date%-%time%
echo %str1%
echo %str2%
echo %str3%
for /f "usebackq tokens=*
delims=" %%D in (`call cscript //Nologo inputbox.vbs %str1% %str2% "%str3%"`) do SET res=%%D
echo %res%
pause
exit /b
VBscript側 [inputbox.vbs]
Option Explicit
REM ------------------------------------------------------
REM inputbox.vbs str1 , str2 [,mode]
REM str1:入力するデータの説明文
REM str2:inputboxのタイトル
REM str3:既定の入力データ
REM (動作)
REM データの入力を行う為の入力ボックスを表示します。
REM 入力された文字列データを返します。
REM str1 中の 「crlf」という文字列は改行に変換します。
REM ------------------------------------------------------
Dim args, arg(99), v, cnt
Dim str1, str2, str3
Dim mode
Dim respond, eLevel
Dim CRLF
REM 改行符号を設定します。
CRLF = chr(13) & chr(10)
Set args = WScript.Arguments
cnt = 1
For Each v In args
arg(cnt) = v
cnt = cnt + 1
Next
eLevel = 0: REM エラーが発生したときに値を設定します。
respond = "": REM 呼び出し元への戻り値を設定します。
REM --------------------------------
REM 改行文字の置き換え
arg(1) = RepExAll (arg(1), "crlf", CRLF)
eLevel = 0
Select Case args.Count
Case 0: mode = InputBox ()
Case 1: mode = InputBox (arg(1))
Case 2: mode = InputBox (arg(1), arg(2))
Case Else: mode = InputBox (arg(1),
arg(2), arg(3))
End Select
respond = mode
REM --------------------------------
REM 結果の表示
WScript.Echo respond
WScript.Quit (eLevel)
REM ここからサブルーチン=========================================
REM 原稿文字列を正規文字列で検索し、一致する文字をすべて置換文字列に置き換えます。
REM s : 原文字列
REM t : 正規文字列
REM d : 置換文字列
Function RepExAll ( s , t , d )
Dim regExpression,
Matches ' 変数を作成します。
Set regExpression = New
RegExp ' 正規表現を作成します。
regExpression.Pattern =
t ' パターンを設定します。
regExpression.IgnoreCase =
True ' 大文字と小文字を区別しないように設定します。
regExpression.Global =
True ' 文字列全体を検索するように設定します。
RepExAll = regExpression.Replace(s ,
d) ' 置換を実行します。
End Function
BAT側 [sleep.bat]
REM スリープ(一時停止)
SET t=6000
SET tm=%date%-%time%
for /f "usebackq tokens=*
delims=" %%D in (`call cscript //Nologo sleep.vbs %t%`) do SET res=%%D
echo %res%
echo %tm% =^> %date%-%time%
pause
exit /b
VBscript側 [sleep.vbs]
Option Explicit
REM ------------------------------------------------------
REM sleep.vbs num
REM num:休止時間数(単位:ミリ秒)
REM (動作)
REM num で指定された時間(ミリ秒)の間、処理を休止します。
REM ------------------------------------------------------
Dim args, arg(99), v, cnt
Dim num
Dim mode
Dim respond, eLevel
Dim CRLF
CRLF = chr(13) & chr(10)
Set args = WScript.Arguments
cnt = 1
For Each v In args
arg(cnt) = v
cnt = cnt + 1
Next
If 1 =< args.Count Then
If 0 =< arg(1) Then
num =
arg(1)
WScript.sleep num
End If
respond = num
eLevel = 0
Else
respond = 0
eLevel = 1
End If
REM 結果の表示
WScript.Echo Ltrim (respond)
WScript.Quit (eLevel)
BAT側 [read_reg.bat]
@title バックアップ
@ECHO off
REM メッセージボックスの表示
SET str="マイ ドキュメントをバックアップしますか?"
SET btn=36
SET res=
FOR /F "usebackq tokens=* delims=" %%D IN (`call cscript //Nologo msgbox.vbs %str% "%btn%"`) DO SET res=%%D
IF NOT "%res%" == "Y" ECHO "「いいえ」が選択されたためバックアップを中止します。"&exit /b
REM マイ ドキュメントのコピー先を設定
SET dist=D:\My Documents\
REM %USERNAME% はユーザー名
SET usr=%USERNAME%
ECHO user=%usr%
REM %~dp0 はこのバッチスクリプトの存在するドライブ名とパスを表します。
REM ("C:\Documents and Settings\<ユーザー名>\My Documents\bat\backup.bat" → "C:\Documents and Settings\<ユーザー名>\My Documents\bat\")
REM VBSをCSCRIPTで起動し、「wscript.ECHO str_path」で出力した文字列をFOR変数「%%I」で受け取り、
REM さらに、SETコマンドで環境変数「ret_value」へ格納します。
REM FOR文のオプションで「usebackq」は「`」ではさまれた部分を実行・処理する対象を指定しています。
REM また、「tokens=*」では、VBSから出力された文字列を「%%I」に受け取ることを指示しています。
FOR /F "usebackq tokens=*" %%I IN (`call cscript //nologo read_reg.vbs`) DO SET ret_value=%%I
REM 「xcopy」を使って、マイ ドキュメントを「D:\」にコピーします。
REM xcopy のオプション、/E は子フォルダも丸ごとコピーします。
REM /R は読み取り専用(ReadOnly)のファイルやフォルダもコピーします。
REM /H は隠し(Hidden)ファイルやシステムファイル、フォルダも丸ごとコピーします。
REM /C はエラーが発生してもコピーを続行します。
REM /Y はコピー先に同一名のファイルやフォルダがあっても確認なしに上書きします。
REM /EXCLUDE: はここで指定されたファイルに含まれる行単位の文字列がファイルのフルパス名に含まれるときにコピーを行わないようにします。
REM /EXCLUDE:without.txt とした場合、without.txtに「.obj」の文字列(行)が含まれていれば、test.objやmain.objなどのファイルはコピーされません。
REM また、without.txtに「\bin\」の文字列(行)が含まれていれば、〜\bin\フォルダはコピーされません。
ECHO ユーザー「%usr%」のマイ ドキュメントへのパスは「%ret_value%」です。
ECHO 「%ret_value%」 を「%dist%」にコピーします。
XCOPY /E /R /H /C /Y /EXCLUDE:dll.txt+sys.txt "%ret_value%" "%dist%"
pause
exit
VBscript側 [read_reg.vbs]
REM ファイル名:read_reg.vbs
Option Explicit
REM ******************************************************************
REM
REM レジストリーから指定のキー値を読み取ります。
REM
REM ******************************************************************
REM 読み込むエントリを定数として宣言。
REM マイ ドキュメント フォルダ - Const REG_KEY = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Personal"
REM マイ ピクチャー フォルダ - Const REG_KEY = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\My Pictures"
REM マイ ミュージック フォルダ - Const REG_KEY = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\My Music"
REM マイ ビデオ フォルダ - Const REG_KEY = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\My Video"
REM お気に入り フォルダ - Const REG_KEY = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Favorites"
REM 共有ドキュメント フォルダ - Const REG_KEY = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\\Explorer\Shell Folders\Common Documents"
REM 共有ピクチャー フォルダ - Const REG_KEY = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\\Explorer\Shell Folders\CommonPictures"
REM 共有ミュージック フォルダ - Const REG_KEY = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\\Explorer\Shell Folders\CommonMusic"
REM 共有ビデオ フォルダ - Const REG_KEY = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\\Explorer\Shell Folders\CommonVideo"
REM オブジェクト変数の宣言とWshShellオブジェクトの作成。
Dim objWshShell
Set objWshShell = WScript.CreateObject("WScript.Shell")
REM RegReadメソッドを使って、Favoritesフォルダの場所を調べる。
Dim str_path
str_path = objWshShell.RegRead(REG_KEY)
REM MsgBox str_path
WScript.Echo str_path
Set objWshShell = Nothing
WScript.Quit
処理によっては、VBscriptからの戻り値を配列(Array)で受け取りたいこともあるでしょう。
この場合、VBscript側で戻り値をバッチの処理にあわせて編集してやる必要があります。
以下の例を参考にしてください。
BAT側 [array.bat]
@title 配列での戻り値
@echo off
echo VBSの戻り値を配列で受け取る。
rem cscript //NoLogo vbs\array.vbs n p q → n, p, q は、配列の名前を与えていますが、バッチとVBSで変数名の整合性が取れていれば特に必要ではありません。
rem バッチの戻り値を受け取る部分は、set %%I のようにしてVBS側で代入文ごと結果を返しています。
rem その気になれば、VBS側で(set n[1]=卵 のように)バッチのコマンドまでお膳立てすることも可能です。
FOR /F "tokens=1-3 delims= " %%F IN ('cscript //NoLogo array.vbs n p q') DO set %%F&set %%G&set %%H
set i=1
:loop
call set chk=%%n[%i%]%%
if "%chk%" == "" goto end_loop
call echo 品名[%i%]:%%n[%i%]%%, 価格[%i%]:%%p[%i%]%%, 数量[%i%]:%%q[%i%]%%
set /a i+=1
goto loop
:end_loop
echo on
exit /b
VBscript側 [array.vbs]
Option Explicit
REM ------------------------------------------------------
REM バッチ処理に配列(Array)で値を返します。
REM ------------------------------------------------------
Dim args, arg(99), v, cnt
Dim respond, eLevel
Dim CRLF
REM 改行符号を設定します。
CRLF = chr(13) & chr(10)
Set args = WScript.Arguments
cnt = 1
For Each v In args
arg(cnt) = v
cnt = cnt + 1
Next
eLevel = 0: REM エラーが発生したときに値を設定します。
respond = "": REM 呼び出し元への戻り値を設定します。
REM --------------------------------
REM ここでは単純に文字列の設定を行っていますが、ファイルの処理やレジストリ操作、HTMLも扱うことができます。
REM 各行内での区切り符号はスペース(空白)と考えています。バッチの呼び出し側(delims)で「,」や「;」などにも変更できます。
respond = arg(1) & "[1]=卵 " & arg(2) & "[1]=200 " & arg(3) & "[1]=50" & CRLF
respond = respond & arg(1) & "[2]=豆腐 " & arg(2) & "[2]=100 " & arg(3) & "[2]=80" & CRLF
respond = respond & arg(1) & "[3]=こんにゃく " & arg(2) & "[3]=150 " & arg(3) & "[3]=40"
REM --------------------------------
REM 結果の表示
WScript.Echo respond
WScript.Quit (eLevel)
参考のためVBScriptからバッチファイルやプログラムの呼び出しを行なう方法を示しておきます。
このスクリプト「exec.vbs」は「fsearch.bat」を呼び出して拡張子が「.txt」のファイルを表示します。
ここでは、バッチの標準出力から検索結果を取得し画面に表示をしています。
タイムアウトは、少し長めで300秒の設定です。
【WshScriptExecの注意点】
1.Execメソッドは、プログラムファイルを起動/実行するものですので、コマンドプロンプトの内部コマンドもバッチファイル化して起動する必要があります。
2.基本的に、ExecメソッドはWscriptで実行した場合、コマンドプロンプトの画面を表示しますので、Cscriptで起動し標準出力への表示は呼び出し元で取得して処置するのがスマートだと思います。
3.タイムアウトに使っているTerminateメソッドによる終了は推奨されていません。安全な終了方法がとれるならそちらを使うべきです。
4.なお、WshScriptExecとは別に「WshScriptRun」メソッドを使うことでもバッチファイルやプログラムを実行できますが、コマンドプロンプトが表示されたり、実行中のプログラムとの通信ができなかったりするので、バッチファイルとの連携を重視する場合は、WshScriptExecメソッドが有利です。
VBScript側 [exec.vbs]
REM -----------------------------------------------------------
REM 外部のプログラムやコマンドを実行します。
REM CmdName:実行するプログラム/コマンドの名前
REM Parameter:引数
REM WshScriptExecのプロパティとメソッド
REM ProcessIDプロパティ :実行を開始したプログラムのプロセスID
REM Statusプロパティ :プログラムのステータス情報(0:実行中、1:終了)
REM ExitCodeプロパティ :プログラムの終了コード
REM StdInプロパティ :実行中プログラムへの標準入力(処理データの引渡しに使用できる。)
REM StdOutプロパティ :実行中プログラムからの標準出力(処理結果の受け取りに使用できる。)
REM StdErrプロパティ :実行中プログラムからのエラー出力(エラー内容を確認できる。)
REM Terminateメソッド :実行中のプログラムを停止させる(タイムアウトなどに利用できる。)
REM -----------------------------------------------------------
Option Explicit
Dim objWsh, objExec
Dim CmdName, Parameter
Dim timeout, tm, t86400
Dim CRLF, rstr, EOJ, ErrorLevel
REM 改行符号の設定
CRLF = Chr(13) & Chr(10)
REM タイムアウト時間(秒)の設定
timeout = 300
tm = Timer() + timeout
t86400 = 0
REM 実行するプログラムの設定
CmdName = "fsearch.bat"
Parameter = ".txt" & " " & "..\"
REM シェルオブジェクトを作成しExecメソッドで実行します。
Set objWsh = WScript.CreateObject ("WScript.Shell")
Set objExec = objWsh.Exec (CmdName & " " & Parameter)
EOJ = False
Do Until EOJ = True
If objExec.StdOut.AtEndOfStream Then
REM 標準出力のデータが無くなったら EOJ を True にする。
EOJ = True
Else
REM 実行結果を標準出力から行単位で読み込み画面に表示ます。
rstr = objExec.StdOut.ReadLine
WScript.Echo rstr
End If
WScript.Sleep 50
REM タイムアウトチェック
If 0 = Timer() Then t86400 = 86400
If tm < Timer() + t86400 Then
If 0 = objExec.Status Then objExec.Terminate
End If
Loop
REM プログラムの実行が終了するまで待機
Do Until objExec.Status = 1
WScript.Sleep 100
REM タイムアウトチェック
If 0 = Timer() Then t86400 = 86400
If tm < Timer() + t86400 Then
If 0 = objExec.Status Then objExec.Terminate
End If
Loop
ErrorLevel = objExec.ExitCode
WScript.Quit ErrorLevel
BAT側 [fsearch.bat]
dir /s %2| find "%1"
連絡先:お問い合わせフォーム