Update:2017/04/28-01:39:00

バッチ処理サンプルスクリプト(使い方?)

Windowsの標準コマンドで作成したプログラム(?)達です。

Windows 2000、XPで使えるようになった拡張機能を利用しています。
たいした処理はしていませんが、何かの参考や役に立てば幸いです。
※Windows 9x/meでは利用できません。ご了承ください。

バッチサブルーチンの使い方

 このバッチサブルーチンはそのままでは大して役に立ちませんが、多少手を入れることで作成したいバッチ処理へ柔軟に対応できると思います。
CやJavaなどを使っておられる方には常識でしょうが、テスト実行用の命令を削除して単一のサブルーチンのみでファイルを保存しておけば、必要に応じてCALLコマンドを使って自由に呼び出すことができ便利だと思います。(INCLUDEやMACRO、REQUIRE機能のように使えます。)
また、引数1が省略された場合や「/?」が指定された場合に使い方の説明を表示するようにしておけばほぼ完璧です。

(例)サンプルの文字列操作に含まれている文字列の検索処理をファイル化します。
 「文字列操作」から太字の部分を取り出し、赤字の部分を追加します。
 編集が終わったら、ファイル名「strpos.bat」で(フォルダー:batlibなどに)保存します。
 バッチから呼び出すときは、「call %lib%strpos 対象文字列 検索文字列」のように呼び出します。
 「%lib%」には、「strpos.bat」へのパスを設定しておきましょう。(例:set lib=batlib\)
 使い方を忘れたときは、コマンドラインから「%lib%strpos /?」で説明を表示します。

文字列操作

文字列操作の基本パターンです。
コマンドプロンプトで使えると便利そうな文字列の長さと文字列の位置検索をサブルーチンにしてみました。
文字列の抽出と置換は環境変数の拡張機能でまかないます。

@title 文字列の操作
@echo off

set str=CommandLine Interface コマンドライン
echo set str=%str%

echo.
echo 文字列の長さ
echo call :strlen %str%
call :strlen "%str%"
echo str=%strlen%

echo.
echo 文字列の検索
echo call :strpos "%str%" "コマンド"
call :strpos "%str%" "コマンド"
echo match=%strpos%

echo.
echo 文字列の抽出
echo str=%str%
echo set substr=%str:~22,4% (%は半角で入力します。)
set substr=%str:~22,4%
echo substr=%substr%

echo.
echo 文字列の置き換え
echo %str:and= & % (%は半角で入力します。)
set str=%str:and= & %
echo str=%str%

echo.
echo on
@exit /b

REM----------------ここからサブルーチン
REM 文字列の長さを求めます。 :strlen
  rem echo on
  set strlen_string=%~1
  set strlen=0
  if "%strlen_string%" == "" goto :EOF
  :strlen_while
    call set ch=%%strlen_string:~%strlen%,1%%
    if "%ch%" == "" goto strlen_wend
    set /a strlen+=1
    goto strlen_while
  :strlen_wend
  rem @echo off
goto :EOF

REM 文字列の位置を求めます。
:strpos
  set source=%~2
  set source_len=0
  :strpos_source_len_while
    call set ch=%%source:~%source_len%,1%%
    if "%ch%" == "" goto strpos_source_len_wend
    set /a source_len+=1
    goto strpos_source_len_while
  :strpos_source_len_wend
  set target=%~1
  set pos=0
  call set wk=%%source:~0,1%%
  :compare_ch
    call set ch=%%target:~%pos%,1%%
    if "%ch%" == "" set pos=0&goto compare_ch_end
    if not "%ch%" == "%wk%" goto compare_ch_next
      call set substring=%%target:~%pos%,%source_len%%%
      if "%substring%" == "%source%" goto compare_ch_end
    :compare_ch_next
    set /a pos+=1
    goto compare_ch
  :compare_ch_end
  set strpos=%pos%
goto :EOF

ファイル名:strpos.bat

REM 文字列の位置を求めます。
:init
if "%~2" == "" set strpos=1& goto :EOF
if "%~1" == "" set strpos=0& goto :EOF
if "%~1" == "/?" goto help
:strpos
  set source=%~2
  set source_len=0
  :strpos_source_len_while
    call set ch=%%source:~%source_len%,1%%
    if "%ch%" == "" goto strpos_source_len_wend
    set /a source_len+=1
    goto strpos_source_len_while
  :strpos_source_len_wend
  set target=%~1
  set pos=0
  call set wk=%%source:~0,1%%
  :compare_ch
    call set ch=%%target:~%pos%,1%%
    if "%ch%" == "" set pos=0&goto compare_ch_end
    if not "%ch%" == "%wk%" goto compare_ch_next
      call set substring=%%target:~%pos%,%source_len%%%
      if "%substring%" == "%source%" goto compare_ch_end
    :compare_ch_next
    set /a pos+=1
    goto compare_ch
  :compare_ch_end
  set strpos=%pos%
goto :EOF

:help
echo %0の使い方
echo 書式:strpos 対象文字列 検索文字列
echo 戻り値:検索文字列の先頭位置 -> strpos == %strpos%
echo  検索文字が見つからなかったとき -> 0
echo  検索文字が""(空文字)の時 -> 1
echo  対象文字が""(空文字)の時 -> 0 (ただし、検索文字が""の時は 1)
echo 分かると思いますが「strpos /? ? 」は、検索できません。(説明画面が出ます。)
goto :EOF



ページトップへ戻る

バッチ処理の作り方

 最近のプログラミングスタイルは、オブジェクト指向によるClassの作成やデータベースを利用したデータオリエンテッドなプログラミングが主流ですが、バッチファイルは頑固なオヤジ風のアルゴリズム中心のプログラミングスタイルがよく似合います。
まあ、言語やプログラミングスタイルに関わらず、プログラムの作成方法はほぼ同じです。
バッチ処理でも、まずは、処理の内容を紙に書いて、必要なデータと処理条件を整理していきます。
システムの開発なんかだと、この段階で評価基準や工数・費用見積もり、テストの仕様、その他プレゼン書類、設計書類を書きまくるわけですね。
バッチ処理では、あまり形式にこだわる必要はないと思いますので(業務用のデータベースを扱うバッチなどは仕様書などがきちんと残ってないと困るかもしれませんが...)ワープロかテキストエディタなんかでざっくりと文書を書いていきます。
で、書いた文書に、より細かい動作やデータの情報を書き加えて、アルゴリズム+データ=プログラミングとします。
作った文書は、そのままドキュメントとして残しておきます。
つぎは、ある時刻から指定時間経過したときの時刻を求めるバッチ処理を作成する例です。

バッチ処理の作成例

時刻計算

 ここでは、ある時刻から指定時間が経過した後の時刻を求めるバッチ処理を作成します。
処理の条件は、
1.時刻は00:00:00から23:59:59の形式の文字列で与え、同様に表示する。
 計算結果として日をまたぐことも考慮する。
2.最初のある時刻は、環境変数に入力して与えるものとする。
 コマンド引数または標準入力から与えられる。
3.経過時間の指定は、環境変数に「秒数」として与えられるものとする。
 コマンド引数または標準入力から与えられる。
4.経過時間の秒数は、整数で負の数を含めて(-2147397248〜2147397247の範囲で)与えられるものとする。
 与える経過時間を -2^31(-2147483648) 〜 2^31-1(2147483647)とすると、計算中に符号が変化し正常に計算ができないため、1日分の秒数(86400)を加減しています。
5.経過時間の計算で日をまたぐ場合は、またぐ日数を結果に付加する。
 例えば結果の表示を days日hh:mm:ss のようにする。
と考えます。

 必要な処理は、次のようになります。
時刻計算
ア.環境変数への時刻の設定
イ.経過時間の設定
ウ.設定時刻と経過時間から計算時刻を求める。

 ここに、もう少し細かいデータと処理の内容を加えます。
時刻計算
ア.環境変数への時刻の設定
 ア−1.コマンド引数のチェックを行いデータが設定されていない場合は、標準入力からの入力を促す。
 ア−2.環境変数に設定された時刻表示が正常な範囲にあるかチェックする。
イ.経過時間の設定
 イ−1.コマンド引数のチェックを行い時刻が設定されていない場合は、標準入力からの入力を促す。
 イ−2.環境変数に設定された経過時間が正常な範囲にあるかチェックする。
ウ.設定時刻と経過時間から計算時刻を求める。
 ウ−1.設定時刻を 00:00:00 からの秒数に変換する。
 ウ−2.設定時刻の秒数に経過時間の秒数を加える。
 ウ−3.計算結果を時刻表示に変換する。

 順次詳細を加えていきます。
時刻計算
ア.環境変数への時刻の設定
 ア−1.コマンド引数のチェックを行いデータが設定されていない場合は、標準入力からの入力を促す。
   引数1が空であれば、キーボードから環境変数 tm に入力
     環境変数 tm が空であれば、現在時刻を環境変数 tm に入力(仕様の変更・追加です。)
   でなければ 引数の値を環境変数 tm に設定
 ア−2.環境変数に設定された時刻表示が正常な範囲にあるかチェックする。
   環境変数 tm が「/?」なら説明画面へ進む
   環境変数 tm から先頭2文字を取り出し、hh へコピー
   hh の先頭1文字目が 0 であれば、hh の2文字目が 0 でなければ、hh の1文字目を削除する。
   hh が -1 より大きいならば、hh が 24 未満であれば、 次へ
   でなければ エラー表示へ進む
   引数1の3文字目から1文字取り出し、変数 delim に格納する
   delim は ":" ならば 次へ でなければ エラー表示へ
   環境変数 tm から先頭2文字を取り出し、mm へコピー
   mm の先頭1文字目が 0 であれば、mm の2文字目が 0 でなければ、mm の1文字目を削除する。
   mm が -1 より大きいならば、mm が 60 未満であれば、 次へ
   でなければ エラー表示へ進む
   引数1の3文字目から1文字取り出し、変数 delim に格納する
   delim は ":" ならば 次へ でなければ エラー表示へ
   環境変数 tm から先頭2文字を取り出し、ss へコピー
   ss の先頭1文字目が 0 であれば、ss の2文字目が 0 でなければ、ss の1文字目を削除する。
   ss が -1 より大きいならば、ss が 60 未満であれば、 次へ
   でなければ エラー表示へ進む
イ.経過時間の設定
 イ−1.コマンド引数のチェックを行い時刻が設定されていない場合は、標準入力からの入力を促す。
   引数2 は "" ならば 変数pastにキーボードから入力させる。
     past は "" ならば pastを0に設定(仕様の変更・追加です。)
   でなければ 引数2を変数pastにコピー
 イ−2.環境変数に設定された経過時間が正常な範囲にあるかチェックする。
   past は -2147397248 より大きいならば
     past は 2147397247 未満ならば、次へ でなければ エラー表示へ
   でなければ エラー表示へ
ウ.設定時刻と経過時間から計算時刻を求める。
 ウ−1.設定時刻を 00:00:00 からの秒数に変換する。
  a)hh * 3600 + mm * 60 + ss → st
 ウ−2.設定時刻の秒数に経過時間の秒数を加える。
  a)st + past → st
 ウ−3.計算結果を時刻表示に変換する。
  a)日数を求めます。
    st / 86400 → days
  b)日数を除いた秒数を求めます。
    st - days * 86400 → st
   (0 > st)か?
      はい st + 86400 → st
         days - 1 → days
    次へ進む
  c)秒数を hh:mm:ss の形式に変換します。
    st / 3600 → ho
    st - ho * 3600 → st
    st / 60 → mo
    st - mo * 60 → st
    st → so
    ho + 100 → ho
    ho の右2桁 → ho
    mo + 100 → mo
    mo の右2桁 → mo
    so + 100 → so
    so の右2桁 → so
    days日ho:mo:so を tt に格納して表示する。

 さらに詳細と修正を加えていきます。
時刻計算
ア.環境変数への時刻の設定
 ア−1.コマンド引数のチェックを行いデータが設定されていない場合は、標準入力からの入力を促す。
  a)(引数1 == "")か?
      はい 環境変数tmにキーボードから入力させる。
        (tm == "")か?
          はい 現在時刻を環境変数tmにコピー
        次に進む
      いいえ 引数1を環境変数tmにコピー
          次へ進む
 ア−2.環境変数に設定された時刻表示が正常な範囲にあるかチェックする。
  a)(tm == "/?")か?
      はい 使い方の説明へ進む
  b)引数1の先頭から2文字取り出し、変数hhに格納する
    (hh の先頭1文字が 0)か?
      はい (hh の2文字目は 0 でない)か?
        はい hh の先頭1文字を削除する。
        いいえ 次へ進む
      いいえ 次へ進む
    (-1 < hh)か?
      はい (24 > hh)か?
           はい 次へ進む
           いいえ エラー表示へ進む
      いいえ エラー表示へ進む
  c)引数1の3文字目から1文字取り出し、変数delimに格納する
    (delim == ":")か?
      はい 次へ進む
      いいえ エラー表示へ進む
  d)引数1の4文字目から2文字取り出し、変数mmに格納する
    (mm の先頭1文字が 0)か?
      はい (mm の2文字目は 0 でない)か?
        はい mm の先頭1文字を削除する。
        いいえ 次へ進む
      いいえ 次へ進む
    (-1 < mm)か?
      はい (60 > mm)か?
           はい 次へ進む
           いいえ エラー表示へ進む
      いいえ エラー表示へ進む
  e)引数1の6文字目から1文字取り出し、変数delimに格納する
    (delim == ":")か?
      はい 次へ進む
      いいえ エラー表示へ進む
  f)引数1の7文字目から2文字取り出し、変数ssに格納する
    (ss の先頭1文字が 0)か?
      はい (ss の2文字目は 0 でない)か?
        はい ss の先頭1文字を削除する。
        いいえ 次へ進む
      いいえ 次へ進む
    (-1 < ss)か?
      はい (60 > ss)か?
           はい 次へ進む
           いいえ エラー表示へ進む
      いいえ エラー表示へ進む
イ.経過時間の設定
 イ−1.コマンド引数のチェックを行い時刻が設定されていない場合は、標準入力からの入力を促す。
  a)(引数2 == "")か?
      はい 変数pastにキーボードから入力させる。
        (past == "")か?
          はい pastを0に設定
        次に進む
      いいえ 引数2を変数pastにコピー
          次へ進む
 イ−2.環境変数に設定された経過時間が正常な範囲にあるかチェックする。
  a)(-2147397248 < past)か?
      はい (2147397247 > past)か?
           はい 次へ進む
           いいえ エラー表示へ進む
      いいえ エラー表示へ進む
ウ.設定時刻と経過時間から計算時刻を求める。
 ウ−1.設定時刻を 00:00:00 からの秒数に変換する。
  a)hh * 3600 + mm * 60 + ss → st
 ウ−2.設定時刻の秒数に経過時間の秒数を加える。
  a)st + past → st
 ウ−3.計算結果を時刻表示に変換する。
  a)日数を求めます。
    st / 86400 → days
  b)日数を除いた秒数を求めます。
    st - days * 86400 → st
   (0 > st)か?
      はい st + 86400 → st
         days - 1 → days
    次へ進む
  c)st / 3600 → ho
    st - ho * 3600 → st
    st / 60 → mo
    st - mo * 60 → st
    st → so
    ho + 100 → ho
    ho の右2桁 → ho
    mo + 100 → mo
    mo の右2桁 → mo
    so + 100 → so
    so の右2桁 → so
    days日ho:mo:so を tt に格納して表示する。
エ.使い方の説明を表示する。
オ.エラー表示を行う。

随時、処理の追加や削除、順序の入れ替えなどを加えます。
詳細が十分書き込まれ、コマンドで置き換えられるようになったらバッチ処理は完成です。
ただし、バッチ処理特有の変数展開やリダイレクト/パイプを行う記号の取り扱いに十分注意してください。
FORコマンドや遅延展開、CALLコマンドの活用などを検討しましょう。
バッチの動作確認が終わったら、エラーの発生条件や処理を実行するための条件、不具合の状況など問題点を洗い出し記録しておきましょう。
(修正するかどうかはともかく、後できっと役に立ちます。)

以下、作成した時刻計算のバッチサンプルです。
@TITLE 時間計算(1)
@echo off
set tm=%~1
if "%tm%" == "" set /p tm=24時間形式(hh 00〜23)で時刻を入力してください。(hh:mm:ss):
if "%tm%" == "" set tm=%TIME:~0,8%
if "%tm%" == "/?" goto HELP
for /f "tokens=1-3 delims=:" %%D in ("%tm%") do set /a hh=%%D&set /a mm=%%E&set /a ss=%%F
rem 時のチェック
if %hh% GEQ 0 (
   if %hh% LSS 24 (
      goto L1
   ) else (
      goto ERR
   )
) else (
   goto ERR
)
:L1
rem 分のチェック
if %mm% GEQ 0 (
   if %mm% LSS 60 (
      goto L2
   ) else (
      goto ERR
   )
) else (
   goto ERR
)
:L2
rem 秒のチェック
if %ss% GEQ 0 (
   if %ss% LSS 60 (
      goto L3
   ) else (
      goto ERR
   )
) else (
   goto ERR
)
:L3

set past=%~2
if "%past%" == "" set /p past=経過秒数を入力してください。:
if "%past%" == "" set /a past=0
if %past% GEQ -2147397248 (
   if %past% LSS 2147397248 (
      goto L4
   ) else (
      goto ERR
   )
) else (
   goto ERR
)
:L4
set /a st = hh * 3600 + mm * 60 + ss
echo 00:00:00からの通算秒数:%st%

rem 時間の計算(本体)
set /a st += past
rem 時刻に経過時間を加えて日をまたいでいる場合の処理
if %st% GEQ 0 set /a days=st / 86400
if %st% LSS 0 set /a days=st / 86400 - 1
rem 日数と時刻を求める
set /a st -= days * 86400
set /a ho = st / 3600
set /a st -= ho * 3600
set /a mo = st / 60
set /a st -= mo * 60
set /a so = st

rem 時分秒を2桁に整形します。
set /a ho += 100
set ho=%ho:~-2%
set /a mo += 100
set mo=%mo:~-2%
set /a so += 100
set so=%so:~-2%
set tt=%days%日%ho%:%mo%:%so%
echo 求める時間は %tt% です。
pause
echo on
@exit/b

:HELP
echo このバッチファイルは、秒単位の数値を加減することで時刻の計算を行います。
echo 計算の結果、日をまたぐことになる場合は、その日数を含めて表示します。
echo 使い方:
echo  %~nx0 [時刻 秒数|/?]
echo  オプション
echo  時刻⇒hh(時):mm(分):ss(秒)の形式で設定します。
echo  秒数⇒±数値の形式で設定します。
echo. /?⇒この画面を表示します。
echo オプションを指定しなかった場合
echo  バッチ処理を起動すると、時刻、秒数を問い合わせてきますので
echo  適宜、設定を行ってください。
echo ※エラー処理は特に行っておりません。
echo ※データの入力にはご注意ください。
echo on
@exit /b

:ERR
echo 指定の時刻、経過時間(秒数)が正常な範囲でありません。
echo 時刻=%tm%、経過時間=%past%
echo 正しい時刻と経過時間を指定してください。
echo on
@exit /b

ページトップへ戻る

【ページ内見出し】
【サイト内リンク】

−広告エリア−
[パソコンと周辺機器のお店]

[3Dプリンタ、メカトロ、ロボットのお店]



元のページに戻る  ページを閉じる

連絡先:お問い合わせフォーム