7. バッチ処理とフローチャート

ここでは、バッチファイルとフローチャートの対応関係について書きます。ソースコードとフローチャートと順番に書くことで、バッチファイルの処理の流れを明確にします。

7.1. goto文

バッチ処理ではgoto文を多用します。構造化プログラミングとは遠い世界です。

gotoの構文

GOTO ラベル

ラベル: バッチ プログラムでラベルとして使用するテキスト文字列を指定します。

ラベルの先頭には : (コロン) を指定し、ラベルだけを単独で 1 行に入力してください。 コマンド拡張機能を有効にすると、GOTO は次のように変更されます。 GOTO コマンドにターゲット ラベルとして :EOF を指定し、現在のバッチスクリプト ファイルの最後に制御を移すことができるようになります。 ラベルを定義しないでバッチ スクリプト ファイルを終了するには、この方法が簡単です。

goto文例
goto文.bat
@echo off

rem ロカール変数を使う時には「setlocal」から「endlocal」で範囲を囲う
setlocal

goto B
:A
rem 処理しない
echo 01

:B
rem 処理する
echo 02
goto D

:C
rem 処理しない
echo 03

:D

endlocal
pause

goto文例のフローチャート
_images/bat_goto_ex.gif

7.2. 三項の条件演算子

バッチ処理には、この構文はありません。
別の節で説明するif...else文を利用しましょう。

※参考:Javaの 三項の条件演算子への参照


7.3. if...else文

※参考:Javaの if...else文への参照

if...elseの構文

IF [NOT] 文字列1==文字列2 コマンド

IF [/I] 文字列1 比較演算子 文字列2 コマンド ELSE コマンド

IF [/I] 文字列1 比較演算子 文字列2 (コマンドs) ELSE (コマンドs)
NOT :条件が偽の場合にだけ、コマンドを実行することを指定します。
コマンド :条件が真のときに実行するコマンドを指定します。コマンドに続けて、ELSE キーワードの後、指定した条件が偽の場合に実行される ELSE コマンドを指定することができます。
コマンドs:複数行のコマンド
比較演算子
EQU - 等しい
NEQ - 等しくない
LSS - より小さい
LEQ - 以下
GTR - より大きい
GEQ - 以上

/I スイッチを指定すると、文字列は、大文字と小文字を区別せずに比較されます。/I スイッチは、IF の 文字列1==文字列2 形式で使うこともできます。この比較は汎用であり、文字列1 と 文字列2 が両方とも数字だけを含む場合は、文字列が数値に変換され、数値の比較が行われます。

if_else.bat

@echo off

rem ロカール変数を使う時には「setlocal」から「endlocal」で範囲を囲う
setlocal
set age=16
set result= 
if %age% GEQ 70 (
	set result= 心の欲する所に従って矩を踰えず
) else if %age% GEQ 60 (
	set result= 耳順う
) else if %age% GEQ 50 (
	set result= 天命を知る
) else if %age% GEQ 40 (
	set result= 惑わず
) else if %age% GEQ 30 (
	set result= 立つ
) else if %age% GEQ 15 (
	set result= 学に志す
) else (
	set result= 無し
)

echo %result% rem =>学に志す
endlocal
pause

if..else文例のフローチャート

_images/rongo.gif

7.4. switch文

バッチ処理には、この構文はありません。しかし、if...else文を使って類似の記述ができます。

※参考:Javaの switch文への参照


switch.bat

@echo off

rem ロカール変数を使う時には「setlocal」から「endlocal」で範囲を囲う
setlocal

set month=2
set result= 
if %month% EQU 1 (
	set result= January
) else if  %month% EQU 2 (
	set result= February
) else if  %month% EQU 3 (
	set result= March
) else if  %month% EQU 4 (
	set result= April
) else if  %month% EQU 5 (
	set result= May
) else if  %month% EQU 6 (
	set result= June
) else if  %month% EQU 7 (
	set result= July
) else if  %month% EQU 8 (
	set result= August
) else if  %month% EQU 9 (
	set result= September
) else if  %month% EQU 10 (
	set result= October
) else if  %month% EQU 11 (
	set result= November
) else if  %month% EQU 12 (
	set result= December
) else (
	set result= err
	exit
)

rem 結果 February
echo %result%
endlocal
pause

switch文例のフローチャート

_images/switch_ex.gif

7.5. for文

バッチ処理にはfor構文がありますが、JavaやC言語と違いbreak、continueはありません。break、continueの代わりに無理にgoto文を使うと副作用が発生することがあるので注意が必要です。また、遅延環境変数(@setlocal EnableDelayedExpansion)を使用可能にすることも検討する必要があります。

※参考:Javaの for文への参照


forの構文

FOR /L %変数 IN (開始,ステップ,終了) DO コマンド [コマンドパラメータ]
%変数: 単一文字の置き換え可能なパラメータを指定します。
セットは、ステップの量ごとに変化する開始から終了までの数列です。
たとえば、(1,1,5) は 1 2 3 4 5、(5,-1,1) は (5 4 3 2 1) という数列になります。

※バッチプログラムで FOR コマンドを使用するときは、%変数の代わりに、%%変数を使用してください。変数名では大文字と小文字が区別されるため、%i と %I は異なります。

1~10の合計を求めるfor文の例
for文1.bat
@echo off

rem ロカール変数を使う時には「setlocal」から「endlocal」で範囲を囲う
setlocal 

set sum=0

rem 書式 for /l %%[変数名] in ([初期値],[増分],[終了値]) do (
for /l %%i in (1,1,10) do (
	rem 四則演算には「set /a」を使う
	set /a "sum = sum + %%i"
)

rem 結果:55
echo %sum% 

endlocal
pause

for文のループの処理を途中で変えたいときには、下記のようにif文とgoto文を組み合わせて擬似的にfor文を作ると副作用を気にする必要がなくなります。

for文.bat

@echo off
setlocal
set sum=0

rem for(i=1;i<=10;i++)
set i=1
:For01
if %i% LEQ 10 (goto Then01) else goto EndFor01
	:Then01
	set /a "sum = i + sum"
	set /a "i = i + 1"
	goto For01
:EndFor01

echo %sum%

endlocal
pause

for文例のフローチャート

_images/for_ex.gif

7.6. for-each文

※参考:Javaの for each文への参照


for inの構文

FOR %変数 IN (セット) DO コマンド [コマンドパラメータ]
%変数: 単一文字の置き換え可能なパラメータを指定します。
(セット): ファイル セットを指定します。ワイルドカードを使用できます。
コマンド: 各ファイルごとに実行するコマンドを指定します。
コマンドパラメータ:
指定されたコマンドのパラメータまたはスイッチを指定します。

※バッチプログラムで FOR コマンドを使用するときは、%変数の代わりに、%%変数を使用してください。変数名では大文字と小文字が区別されるため、%i と %I は異なります。
1~10の合計を求めるfor文の例
for_each文1.bat
@echo off

rem ロカール変数を使う時には「setlocal」から「endlocal」で範囲を囲う
setlocal 

set sum=0

rem for %変数 in (セット) do コマンド [コマンドパラメータ] 
for %%i in (1 2 3 4 5 6 7 8 9 10) do (
	rem 四則演算には「set /a」を使う
	set /a "sum = sum + %%i"
)

rem 結果:55
echo %sum% 

endlocal
pause

if文とgoto文を組み合わせて擬似的にfor_each文を作る場合は下記となります。

for_each文.bat

@echo off
setlocal

set nums[1]=1
set nums[2]=2
set nums[3]=3
set nums[4]=4
set nums[5]=5
set nums[6]=6
set nums[7]=7
set nums[8]=8
set nums[9]=9
set nums[10]=10
rem または for %%i in (1 2 3 4 5 6 7 8 9 10) do set nums[%%i]=%%i

set nums_count=10
set sum=0

rem for(num in nums)
set i=1
:ForEach01
if %i% LEQ %nums_count% (goto Then01) else goto EndForEach01
	:Then01
	set num=%nums[%%i%%]%
	set /a "sum = sum+num"
	set /a "i = i + 1"
	goto ForEach01
:EndForEach01
rem end for

echo %sum%

endlocal
pause

for each文例のフローチャート

_images/for_each.gif

7.7. while文

バッチ処理には、この構文はありません。しかし、if...else文とgoto文を使って類似の記述ができます。

※参考:Javaの while文への参照


1~10の合計を求める例
while文.bat
@echo off
setlocal
set i=1
set sum=0

rem while(i<=10)
:While01
if %i% LEQ 10 (goto Then01) else goto EndWhile01
	:Then01
	set /a "sum = i + sum"
	set /a "i = i + 1"
	goto While01
:EndWhile01
rem end while

echo %sum%

endlocal
pause

while文例のフローチャート

_images/while_ex.gif

7.8. do..while文

バッチ処理には、この構文はありません。しかし、if...else文とgoto文を使って類似の記述ができます。

※参考:Javaの do while文への参照


1~10の合計を求める例
do_while文.bat
@echo off
setlocal
set i=1
set sum=0

rem do
:DoWhile01
	set /a "sum = i + sum"
	set /a "i = i + 1"
	if %i% LEQ 10 (goto DoWhile01)
rem while(i<=10)

echo %sum%

endlocal
pause

do_while文例のフローチャート

_images/do_while_ex.gif

7.9. continue文

バッチ処理にはfor構文がありますが、JavaやC言語と違いbreak、continueはありません。break、continueの代わり無理にgoto文を使おうとすると副作用が発生することがあるので注意が必要です。

※参考:Javaの continue文への参照


if文とgoto文を組み合わせて擬似的にfor文を作る場合は下記となります。

for_continue文.bat

@echo off
setlocal
set sum=0

rem for(i=1;i<=10;i++)
set i=1
:For01
if %i% LEQ 10 (goto Then01) else goto EndFor01
	:Then01
	rem if(i==3)
	if %i% EQU 3 goto Continue01
	set /a "sum = i + sum"
	:Continue01
	set /a "i = i + 1"
	goto For01
:EndFor01
rem end for

rem 結果は52
echo %sum%

endlocal
pause

continue文例のフローチャート

_images/bat_for_continue_ex.gif

7.10. break文

バッチ処理にはfor構文がありますが、JavaやC言語と違いbreak、continueはありません。break、continueの代わり無理にgoto文を使おうとすると副作用が発生することがあるので注意が必要です。

※参考:Javaの break文への参照


if文とgoto文を組み合わせて擬似的にfor文を作る場合は下記となります。

for_break文.bat

@echo off
setlocal
set sum=0

rem for(i=1;i<=10;i++)
set i=1
:For01
if %i% LEQ 10 (goto Then01) else goto EndFor01
	:Then01
	set /a "sum = i + sum"
	rem if(sum>=30)
	if %sum% GEQ 30 goto Break01
	set /a "i = i + 1"
	goto For01
:Break01
:EndFor01
rem end for

echo %sum%

endlocal
pause

break文例のフローチャート

_images/bat_for_break_ex.gif

7.11. ラベル付きcontinue文

バッチ処理には、この構文はありません。しかし、goto文を使って類似の記述ができます。

※参考:Javaの ラベルcontinue文への参照


for_double_continue文.bat
@echo off
setlocal
set sum=0

rem  Label:for(i=1;i<=10;i++)
set i=1
:For01
if %i% LEQ 10 (goto Then01) else goto EndFor01
	:Then01
	rem for(j=1;j<=10;j++)
	set j=1
	:For02
	if %j% LEQ 10 (goto Then02) else goto EndFor02
		:Then02
		rem if(i==3) continue Lable;
		if %i% EQU 3 goto LbCnt01
		set /a "sum = sum + i * j"
		set /a "j = j + 1"
		goto For02
	:EndFor02
	rem end for

	:LbCnt01
	set /a "i = i + 1"
	goto For01
:EndFor01
rem end for

rem rem 結果は2860
echo %sum%

endlocal
pause

ラベル付きcontinue文例のフローチャート

_images/bat_for_double_continue_ex.gif

7.12. ラベル付きbreak文

バッチ処理には、この構文はありません。しかし、goto文を使って類似の記述ができます。

※参考:Javaの ラベルbreak文への参照


for_double_break文.bat

@echo off
setlocal
set sum=0

rem Label:for(i=1;i<=10;i++)
set i=1
:For01
if %i% LEQ 10 (goto Then01) else goto EndFor01
	:Then01
	rem for(j=1;j<=10;j++)
	set j=1
	:For02
	if %j% LEQ 10 (goto Then02) else goto EndFor02
		:Then02
		set /a "sum = sum + i * j"
		rem if(sum>=15) break Lable;
		if %sum% GEQ 15 goto LbBrk01
		set /a "j = j + 1"
		goto For02
	:EndFor02
	rem end for

	set /a "i = i + 1"
	goto For01
	:LbBrk01
:EndFor01
rem end for

rem 結果は15
echo %sum%

endlocal
pause

ラベル付きbreak文例のフローチャート

_images/bat_for_double_break_ex.gif