Windowsバッチファイル

バッチファイルのサブルーチンと関数【call・goto・ラベルの作り方】

Windowsバッチファイル
記事内に広告が含まれています。

バッチファイルでも「同じ処理を何度も書く」のを避けるためにサブルーチン(関数)が使えます。callgoto・ラベルを組み合わせた仕組みを、動作原理から丁寧に解説します。

ラベルとgotoの基本

バッチファイルでは「:ラベル名」でジャンプ先を定義し、「goto ラベル名」でそこへ飛びます。ラベルはコロン(:)で始まる行です。

@echo off

echo 処理開始
goto :STEP2

echo ← ここは飛ばされる(実行されない)

:STEP2
echo STEP2から再開
pause

ただし goto の多用はコードが読みにくくなる「スパゲッティコード」になりやすいため、単純なジャンプより後述の call でサブルーチン化するのが推奨です。

callでサブルーチンを呼び出す

call :ラベル名 でサブルーチンを呼び出し、サブルーチン内で exit /b を使うと呼び出し元に戻ります。これがバッチファイルの「関数」の仕組みです。

@echo off

rem メイン処理
call :SHOW_HEADER
echo 本文の処理
call :SHOW_FOOTER
pause
exit /b 0   ← ここでバッチ全体を終了(サブルーチンに落ちないようにする)

rem ===== サブルーチン =====
:SHOW_HEADER
echo ==============================
echo   バッチファイル処理ツール
echo ==============================
exit /b 0   ← callで呼ばれたら exit /b で呼び出し元に戻る

:SHOW_FOOTER
echo ==============================
echo   処理が完了しました
echo ==============================
exit /b 0

重要ポイント:メイン処理の末尾に必ず exit /b 0 を書かないと、実行がそのままサブルーチンまで流れてしまいます。これはバッチ初心者が必ずハマる落とし穴です。

引数を渡してサブルーチンを汎用化する

サブルーチンに引数を渡すことで、汎用的な「関数」を作れます。%~1%~2 でサブルーチン内の引数を参照します(チルダ付きでクォートを取り除く)。

@echo off

rem 引数付きサブルーチンの呼び出し
call :BACKUP "C:\work" "D:\backup"
call :BACKUP "C:\docs" "D:\backup"
pause
exit /b 0

rem ===== サブルーチン:バックアップ処理 =====
rem %~1 = 第1引数(コピー元)、%~2 = 第2引数(コピー先)
:BACKUP
set SRC=%~1
set DST=%~2
echo バックアップ: %SRC% → %DST%
if not exist "%DST%" mkdir "%DST%"
robocopy "%SRC%" "%DST%" /E /XO
if %errorlevel% leq 7 (
    echo   完了
) else (
    echo   エラー発生!
)
exit /b 0

戻り値を変数で受け取る

バッチファイルには正式な「戻り値」の仕組みはありませんが、サブルーチン内でセットした変数はメインからも参照できることを利用して値を返します。

@echo off

rem サブルーチンを呼び出して結果を取得
call :GET_TIMESTAMP
echo タイムスタンプ: %TIMESTAMP%
pause
exit /b 0

rem ===== 日時文字列を作るサブルーチン =====
:GET_TIMESTAMP
set TIMESTAMP=%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%_%TIME:~0,2%%TIME:~3,2%%TIME:~6,2%
set TIMESTAMP=%TIMESTAMP: =0%   ← 空白を0で置換(時間が1桁のとき対策)
exit /b 0

setlocalとendlocalでスコープを分ける

setlocal を使うとサブルーチン内で定義した変数がメインに影響しないよう「スコープ」を分けられます。大きなバッチでは積極的に使いましょう。

:MY_FUNC
setlocal
set TEMP_VAR=これはローカル変数
echo %TEMP_VAR%
endlocal        ← ここでTEMP_VARは消える
exit /b 0

まとめ

  • call :ラベル名 でサブルーチンを呼び出し、exit /b 0 で呼び出し元に戻る
  • メイン処理の末尾に exit /b を書かないとサブルーチンに流れ込む(よくある落とし穴)
  • %~1・%~2 でサブルーチンへの引数を受け取れる(チルダでクォートを除去)
  • 戻り値は変数にセットしてメインから参照する方式で実現する
  • setlocal / endlocal でサブルーチン内の変数スコープを分けられる

バッチファイルを書き始めた頃、メイン処理末尾のexit /bを書き忘れてサブルーチンが二重に実行されるバグで1時間悩んだことがあります。今でも必ずサブルーチンの前にexit /bを書くようにしています。

hobbyshift管理人

コメント

タイトルとURLをコピーしました