まくまくWindowsノート
バッチファイルで関数もどき(サブルーチン)を実現する
2015-02-09

バッチファイルにおけるサブルーチンの定義

バッチファイルで関数は定義できませんが、call でラベルにジャンプすることで、サブルーチンとして実行できます。 goto でジャンプしてしまうと、ジャンプ先のコマンド群を実行した後に戻ってきてくれませんが、call でジャンプすれば、呼び出し位置に戻ってきてくれます。 下記の例では、関数もどきとして、MyFunc1MyFunc2 を定義し、呼び出しています。

sample.bat

@echo off

REM === メインシーケンス
call :MyFunc1
call :MyFunc2
exit /b

REM === 関数 1
:MyFunc1
echo Hello, I am MyFunc1
exit /b

REM === 関数 2
:MyFunc2
echo Hello, I am MyFunc2
exit /b

実行結果

Hello, I am MyFunc1
Hello, I am MyFunc2

それぞれのシーケンス(メイン、関数1、関数2)の最後で、exit /b を実行しなければいけないことに注意してください。 そうしないと、それぞれのシーケンスで、バッチファイルの最後まで実行してしまいます(その場合も call 呼び出し位置に戻ってきます)。

別のバッチファイルを呼び出す

ちなみに、call コマンドでは、別ファイルのバッチファイルを呼び出すこともできます。 サブルーチンの呼び出しでは、先頭にコロン : を付けますが、この場合は代わりにバッチファイル名を指定します。

call %~dp0\SubModule.bat    (拡張子 .bat は省略可能)

先頭の %~dp0\ は、バッチファイルの含まれているディレクトリを表すおまじないです。 これを入れることにより、バッチファイルのあるディレクトリ以外から実行した場合に、正しく別のバッチファイルを参照できるようになります。

サブルーチンに引数を渡す

サブルーチンに渡されたパラメータは、%1%2 などで取得することができます。

sample.bat

@echo off

REM === メインシーケンス
call :MyFunc aaa bbb
call :MyFunc "aaa bbb"
exit /b

REM === 関数定義
:MyFunc
echo %1
exit /b

実行結果:

aaa
"aaa bbb"

パラメータ内にスペースや特殊な記号を含む場合は、ダブルクォーテーション " で囲めばよいのですが、%1 で取得した結果にダブルクォーテーションが含まれてしまいます(上記サンプルの "aaa bbb" という出力結果)。 ダブルクォーテーションを削除した結果を取得したい場合は、以下のようにチルダ ~ を使います。

echo %~1

サブルーチン内でローカル変数を定義する

バッチファイル内で変数を定義するときに、SET の代わりに SETLOCAL を使うと、ENDLOCAL を呼び出すことで SETLOCAL 呼び出し時の定義状態に戻すことができます。 これを利用することで、サブルーチン内だけで参照可能なローカル変数を表現できます。 なお、サブルーチンから戻る際には、自動的に ENDLOCAL されるので、実際には、サブルーチンの先頭で SETLOCAL しておくだけで大丈夫です。

sample.bat

@echo off

set VAL=100
echo %VAL%
call :MyFunc
echo %VAL%
exit /b

:MyFunc
setlocal
set VAL=200
echo %VAL%
exit /b

実行結果

100
200
100
2015-02-09