
次のようなコードを書こうとしています:
If %dropmode%==on (
If %drop% LEQ %potiondrop% (
set /a potion=%potion%+1
)
If %drop2% LEQ %potiondrop% (
set /a potion=%potion%+1
)
)
つまり、条件「if %drop2% LEQ %potiondrop%」は機能しませんが、「if %drop% LEQ %potiondrop%」は機能します。どうすればよいでしょうか?
答え1
問題は、CMD.EXEとして知られるWindowsコマンドプロンプト/コマンドラインインタープリター(CLI)にバグ(まあ、マイクロソフトはそれを機能だと思っているのでしょうが)があり、ループIF … ( … )
のようなブロック構造を読み込むとFOR
、すべての変数を解釈してしまうことです。%variable_name%
すぐにループまたはブロックが実行される前に を実行します。例では、ブロックpotion
に入ったときに が 0 の場合If %dropmode%==on ( … )
、そのブロック内のすべての の発生は0 と評価されるため、ブロック内で を変更しても、%potion%
両方のset
ステートメントは として処理されます。これは、報告された画面出力から明らかです。set /a potion=0+1
potion
修正方法は、変数を参照するステートメントが実行されたときに、適切なタイミングで変数を展開するようにCMDに指示することです。これを行うには、
setlocal enabledelayedexpansion
バッチファイルの先頭付近で、カウントコードを次のように変更します。
set /a potion=!potion!+1
フォームを使用して遅延拡張を有効にします。詳細については、およびを参照してください。!variable_name!
SET /?
SETLOCAL /?
PS 別の解決策としては、単に文%
から文字を削除して次のようset
に言うことです。
set /a potion=potion+1