このサイトには広告リンクが含まれます。

バッチファイルでフォルダを自動生成しようとしてハマったことメモ

息子の写真を保存するフォルダを自動生成できたら楽ちん! と思って、Windowsのバッチファイルを書いてみました。(注:上級者向けです)
めっっちゃハマって、ググりまくりながら書いたので、詰まったところをメモします。
バッチファイル、クセ強すぎ・・・!

スポンサーリンク

変数に値を代入するとき、変数名と値の前後に、余分な半角スペースを入れてはいけない

半角スペースを含んだ変数名や値になってしまいます。なんだそれ。

× SET year = 2021
○ SET year=2021
× IF 条件 ( SET filename=%filename%%year%_ )
○ IF 条件 (SET filename=%filename%%year%_)

変数に計算結果を代入するときは/aを付ける。変数は展開する

こんな感じ。展開しないと、変数名の文字列になってしまいました。

× SET month=month+1
× SET /a month=month+1
○ SET /a month=%month%+1

変数の中身を比較や計算したいときは%%で囲む

これも囲まないと展開されなくて、変数名の文字列として比較されちゃいます。

× IF start_day LSS 10
○ IF %start_day% LSS 10

比較演算子は英語

数値を比較するときは、=や>ではなく、EQUとかGTRとか使います。ぐぐったらでてくるよ!(思考停止)

FOR文は、%%i の扱いが面倒すぎるので、使わない! ラベルループを使う!(思考停止)

rem ○ ラベルループってこんな感じ
SET count=1
SET max_count=5
:loop
rem やりたい処理
SET /a count=%count%+1
IF %count% GTR %max_count% GOTO :eof
GOTO :loop

IF節の中で更新した変数を、そのIF節の中で比較や出力するときは、遅延展開を使う

該当行を”setlocal enabledelayedexpansion”および”endlocal”で囲って、変数は!!で囲んで展開します。
IF節はまるごと1行と認識されるらしく、デフォルトだとIF節の読み込み時に即時展開されてしまいます。まじかよ。

rem × これは期待した動きをしない
IF %last_day% GTR 31 (
  SET /a month=%month%+1
  rem 翌年に入った場合
  IF %month% GTR 12 (
    SET month=1
    SET /a year=%year%+1
  )
)

rem ○ これで期待通り
setlocal enabledelayedexpansion
IF %last_day% GTR 31 (
  SET /a month=%month%+1
  rem ↓ここ変わったよ
  IF !month! GTR 12 (
    SET month=1
    SET /a year=%year%+1
  )
)
endlocal

配列はないらしいので、変数のおしりに通し番号を付けて、配列もどきを作って使ったよ

配列もどきの変数を展開するときは、遅延展開の!!を使って、まず通し番号を展開→のちに変数全体を展開、と二段構えで展開するといいよ。

rem ○ こんな感じ
SET month_last_day=!month_last_day%month%!

文字化け対策(日本語名のフォルダを生成したい)

コマンドプロンプトはデフォルトがShift-JISらしく、UTF-8のバッチファイルを走らせると文字化けします。
文字コードを指定するコマンド(下記)をバッチファイル先頭に書いて解決(65001がUTF-8を示す)

rem × これだけだと化ける
mkdir "てすと"

rem ○ 化けない!
chcp 65001
mkdir "てすと"

完成したコード

無事こんなの出来ました!
1週間毎の開始日・終了日の入ったフォルダを、指定した日付を起点に、指定した数だけ生成します。各フォルダの中には「絞り込み」フォルダも生成されます。
楽になりました! ぱちぱち。

chcp 65001

rem 以下の変数を手動で設定し、コマンドプロンプトを起動して実行しましょう
rem 1週間毎の日付の入ったフォルダを、max_countの数だけ生成します
SET year=2021
SET print_year=false
SET month=9
SET month_last_day=30
SET month_0ume=09
SET start_day=20
SET max_count=13
rem うるう2月のフォルダを生成するなら、下の month_last_day2 も変更しましょう(使い終わったら元に戻してね)

SET month_last_day1=31
SET month_last_day2=28
SET month_last_day3=31
SET month_last_day4=30
SET month_last_day5=31
SET month_last_day6=30
SET month_last_day7=31
SET month_last_day8=31
SET month_last_day9=30
SET month_last_day10=31
SET month_last_day11=30
SET month_last_day12=31

SET count=1

setlocal enabledelayedexpansion
:loop
	IF %print_year%==true (SET filename=%year%_%month_0ume%) ELSE (SET filename=%month_0ume%)
	IF %start_day% LSS 10 (SET filename=%filename%0%start_day%-) ELSE (SET filename=%filename%%start_day%-)
	SET /a last_day=%start_day%+6
	
	rem 最後の日が翌月になった場合
	IF %last_day% GTR %month_last_day% (
		SET /a last_day=%last_day%-%month_last_day%
		SET /a month=%month%+1
		
		rem 翌年に入った場合
		IF !month! GTR 12 (
			SET month=1
			SET /a year=%year%+1
			SET filename=%filename%!year!_
		)
		IF !month! LSS 10 (SET month_0ume=0!month!) ELSE (SET month_0ume=!month!)
		SET filename=!filename!!month_0ume!
	)
	
	IF %last_day% LSS 10 (SET filename=%filename%0%last_day%) ELSE (SET filename=%filename%%last_day%)
	
	mkdir %filename%
	cd %filename%
	mkdir "絞り込み"
	cd ..
	
	SET /a start_day=%start_day%+7
	IF %start_day% GTR %month_last_day% (
		SET /a start_day=%start_day%-%month_last_day%
	)
	IF %start_day% EQU 1 (
		SET /a month=%month%+1
		IF !month! GTR 12 (
			SET month=1
			SET /a year=%year%+1
			echo year=!year!
		)
		IF !month! LSS 10 (SET month_0ume=0!month!) ELSE (SET month_0ume=!month!)
	)
	SET month_last_day=!month_last_day%month%!

	SET /a count=%count%+1
	IF %count% GTR %max_count% GOTO :eof
GOTO :loop
endlocal
プログラミング
文月をフォローする
スポンサーリンク
スポンサーリンク
こちらもいかが?
青空庭園

コメント

スポンサーリンク
タイトルとURLをコピーしました