Reputation: 497
The following if statement is not running. It just ends the bat file It stops the process. Why is this happening? How do I stop it?
if "%Choice%"=="si" (GOTO Case2) else (
if "%Choice%"=="s" (GOTO Case1) else (
if "%Choice%"=="ti" (GOTO Case4) else (
if "%Choice%"=="t" (GOTO Case3) else (
if "%Choice%"=="i" (GOTO Case5) else (
if "%Choice%"=="cp" (GOTO Case6) else (
if "%Choice%"=="kp" (GOTO Case7) else (
if "%Choice%"=="?" (GOTO CaseHelp) else (
if "%Choice%"=="c" (GOTO Case8) else (
if "%Choice%"=="sl" (GOTO Case9) else (
if "%Choice%"=="sf" (GOTO Case10) else (
if "%Choice%"=="fz" (GOTO Case11) else (
if "%Choice%"=="dc" (GOTO Case12) else (
if "%Choice%"=="cm" (GOTO Case12) else (
if "%Choice%"=="wh" (GOTO Case13) else (
if "%Choice%"=="vs" (GOTO Case14) else (
if "%Choice%"=="it" (GOTO Case15) else (
if "%Choice%"=="tm" (GOTO Case16) else (
if "%Choice%"=="d" (GOTO Case17) else (
if "%Choice%"=="ed" (GOTO Case18) else (
if "%Choice%"=="be" (GOTO Case19) else (
if "%Choice%"=="me" (GOTO Case20) else (
if "%Choice%"=="ap" (GOTO Case21) else (
if "%Choice%"=="pc" (GOTO Case22) else (
if "%Choice%"=="sc" (GOTO Case23) else (
if "%Choice%"=="c" (GOTO Case24) else (
if "%Choice%"=="ll" (GOTO Case25) else (
if "%Choice%"=="ij" (GOTO Case26) else (
GOTO CaseError)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
Also, is there an alternative of using an if statement as this method is uite time consuming.
Upvotes: 0
Views: 3217
Reputation: 130919
Well, I see 28 opening (
, but only 24 closing )
, so it can't possibly work.
You don't show your complete relevant code, we can't see if you have all the required labels.
PaulF has a good point in his comment, since each IF does a GOTO, you don't need any ELSE statements.
if "%Choice%"=="si" GOTO Case2
if "%Choice%"=="s" GOTO Case1
if "%Choice%"=="ti" GOTO Case4
etc...
if "%Choice%"=="ij" GOTO Case26
goto CaseError
But let's suppose that you are not doing GOTO with each IF, but rather something else. There is no need to do a lot of indents, and you don't need so many parens. Batch does not formally have an ElseIf, but it functionally works just as well if you use ELSE IF. Look how I arrange the parens and indents - it is much easier to read and follow the code.
if "%Choice%"=="xxx" (
do something
) else if "%Choice%"=="yyy" (
do something else
) else if "%Choice%"=="zzz" (
do something different
) else (
everything else gets to here
)
Since you are performing GOTOs, there is another option. Incorporate the %Choice% value in the :label, and then you don't need any IF statement, other than to verify that the choice is valid, and take special action if it isn't.
Opion 1: Define the list of valid entries, and use find/replace to test if the choice is amongst the valid options. This is best done with delayed expansion. Note the leading and trailing space in the options list is important in this technique.
setlocal enableDelayedExpansion
set "options= si s ti t i cp kp ? c sl sf fz dc cm wh vs it tm d ed be me ap pc sc c ll ij "
set "choice="
set /p "choice=Enter your choice: "
if "!options: %choice% =!" neq "!options!" goto case_%choice%
goto case_error
:case_si
rem do something
exit /b
:case_s
rem do something else
exit /b
etc...
Option 2: Use FINDSTR to probe the batch file itself to verify the label exists. Here I am using a simplified search that will not handle all possible arrangements of valid labels. But it should be fine as long as you don't get creative with how you create your labels.
set "choice="
set /p "choice=Enter your choice: "
findstr /i /r /c:"^:case_%choice%$" /c:"^:case_%choice% " "%~f0" >nul 2>nul && goto :case_%choice%
goto :case_error
:Case_si
rem do something
exit /b
:Case_s
rem do something else
exit /b
etc...
Upvotes: 4
Reputation: 49186
I suggest to use the command CHOICE for this large selection between 28 options:
@echo off
:Menu
cls
echo 1 ... option 1
echo 2 ... option 2
echo and so on
echo 9 ... option 9
echo a ... option 10
echo and so on
echo r option 27
echo 0 ... help
echo/
%SystemRoot%\System32\choice.exe /C 123456789abcdefghijklmnopqr0 /N /M "Your choice: "
goto Case%ERRORLEVEL%
:Case1
echo Option 1
goto :EOF
:Case2
echo Option 2
goto :EOF
rem And so on
:Case28
cls
echo Help
echo/
pause
goto :Menu
Command CHOICE does not allow any invalid input. It waits with the used options until the user presses any key as specified after parameter /C
and assigns to ERRORLEVEL
the number according to index of the appropriate key/character in the list, i.e. 1 for first 1
, 2 for second 2
and 28 for last key/character 0
. Run in a command prompt window choice /?
for help on this command.
goto Case%ERRORLEVEL%
is not working if the entire menu code is within a command block starting with (
and ending with matching )
because variable reference %ERRORLEVEL%
is replaced already by current value of environment variable ERRORLEVEL
before the command left to (
is executed at all.
Delayed expansion must be enabled in this case and goto Case!ERRORLEVEL!
must be used to get the GOTO working within a command block. Run in a command prompt set /?
and read the hep output on several window pages for details about delayed expansion as well as setlocal /?
used to enable delayed expansion and endlocal /?
to restore previous command environment.
An alternate solution for the menu within a command block without using delayed environment variable expansion is replacing the command line goto Case%ERRORLEVEL%
by
for /L %%X in (28,-1,1) do if errorlevel %%X goto Case%%X
See the Microsoft support article about Testing for a Specific Error Level in Batch Files why the decrementing FOR loop with the if errorlevel X
condition executing goto CaseX
works within a command block without usage of delayed expansion.
Upvotes: 2
Reputation: 67256
I think this is the simplest way to solve this problem:
@echo off
setlocal
set /p "Choice= Which Service? "
call :Case-%choice% 2> NUL
if errorlevel 1 goto CaseError
goto :EOF
:Case-si
echo You select "si" service
exit /B
:Case-s
echo You select "s" service
exit /B
:Case-etc
echo You select "etc" service
exit /B
:CaseError
echo Error: invalid service...
goto :EOF
When a call
with a non-defined label is executed, the system automatically set ERRORLEVEL to one and continue to the next line, so you just need an if
to detect such an error...
Using this method you don't need to check for each one of the options, just include the desired code below each one of the proper :Case-serviceNameHere
labels and that is it!
Upvotes: 1