'Problem to reassign a value to an existing batch variable

I'm struggling with this little annoyance in a batch file:

This is beginning the code:

SET CAMFORLARGEPARTS=YES
IF "%CAMFORLARGEPARTS%" EQU "NO" (SET REGISTRYFILEPARTSIZES=Normal_Parts) ELSE (SET REGISTRYFILEPARTSIZES=Large_Parts)
SET PROMPTFORPARTSIZE=YES

Down the road, we have this as well, in the same .cmd file

I am trying, without success, to reassign a different value to %CAMFORLARGEPARTS%

:ASKABOUTPARTSIZE
ECHO OFF
IF "%PROMPTFORPARTSIZE%" NEQ "YES" GOTO SKIPTHIS

CHOICE /C YN /N /T 10 /D Y /M "USE LARGE PARTS? -> PRESS 'Y' FOR YES | 'N' FOR NO"
ECHO ON
ECHO.
ECHO THE ERRORLEVEL VALUE RETURNED BY CHOICE.EXE IS %ERRORLEVEL%

IF ERRORLEVEL 1 SET CAMFORLARGEPARTS=YES
IF ERRORLEVEL 2 SET CAMFORLARGEPARTS=NO
ECHO.
ECHO THE VALUE SET FOR VARIABLE CAMFORLARGEPARTS IS %CAMFORLARGEPARTS%

PAUSE

EXIT

:SKIPTHIS
...

These are the results I'm getting. I don't understand why even receiving and passing the correct errorlevel based on the user s input, I'm alkways getting %CAMFORLARGEPARTS% set as YES.

What am I doing wrong here?

enter image description here

enter image description here

Thanks a million!



Solution 1:[1]

Based upon my commented advice, here's an example which doesn't change your structure too much.

:ASKABOUTPARTSIZE
@ECHO OFF
IF /I NOT "%PROMPTFORPARTSIZE%" == "YES" GOTO SKIPTHIS

%SYSTEMROOT%\SYSTEM32\CHOICE.EXE /C YN /N /T 10 /D Y /M "USE LARGE PARTS? -> PRESS 'Y' FOR YES | 'N' FOR NO"
SET "CHOICECODE=%ERRORLEVEL%"

ECHO(
ECHO THE ERRORLEVEL VALUE RETURNED BY CHOICE.EXE IS %CHOICECODE%

IF %CHOICECODE% EQU 2 (SET "CAMFORLARGEPARTS=NO") ELSE SET "CAMFORLARGEPARTS=YES"

ECHO(
ECHO THE VALUE SET FOR VARIABLE CAMFORLARGEPARTS IS %CAMFORLARGEPARTS%

PAUSE

EXIT /B

:SKIPTHIS
…

Solution 2:[2]

As you choice command has only 2 options, a simple method is to use an else statement and only evaluate errorlevel 2

It is important to not have ANY other commands between choice and if errorlevel

@echo off
CHOICE /C YN /N /T 10 /D Y /M "USE LARGE PARTS? -> PRESS 'Y' FOR YES | 'N' FOR NO"

IF ERRORLEVEL 2 (
    SET "CAMFORLARGEPARTS=NO"
) else (
    set "CAMFORLARGEPARTS=YES"
)
echo %CAMFORLARGEPARTS%

Alternatively you can still evaluate each errorlevel and simply use goto statements. This has to be in descending order else it will not work:

@echo off
CHOICE /C YN /N /T 10 /D Y /M "USE LARGE PARTS? -> PRESS 'Y' FOR YES | 'N' FOR NO"

If ERRORLEVEL 2 goto :CAM2
If ERRORLEVEL 1 goto :CAM1
If ERRORLEVEL 0 exit /b
goto :EOF  
:CAM2
SET "CAMFORLARGEPARTS=NO"
goto :result
:CAM1
SET "CAMFORLARGEPARTS=YES"
:result
echo %CAMFORLARGEPARTS%

Solution 3:[3]

Strictly not an answer, since there's no problem with the original code as posted.

Code tested:

@ECHO Off
SETLOCAL
cls

ECHO.&ECHO --- As posted --- but with ECHO turned off

CHOICE /C YN /N /T 10 /D Y /M "Use Large Parts? -> Press 'Y' for Yes | 'N' for No
ECHO.
ECHO The errorlevel value returned by choice.exe is %ERRORLEVEL%

IF ERRORLEVEL 1 SET CAMFORLARGEPARTS=YES
IF ERRORLEVEL 2 SET CAMFORLARGEPARTS=NO
ECHO.
ECHO The value set for variable CAMFORLARGEPARTS is %CAMFORLARGEPARTS%
CHOICE /C YN /N /T 10 /D Y /M "Use Large Parts? -> Press 'Y' for Yes | 'N' for No
ECHO.
ECHO The errorlevel value returned by choice.exe is %ERRORLEVEL%

IF ERRORLEVEL 1 SET CAMFORLARGEPARTS=YES
IF ERRORLEVEL 2 SET CAMFORLARGEPARTS=NO
ECHO.
ECHO The value set for variable CAMFORLARGEPARTS is %CAMFORLARGEPARTS%

echo.&ECHO --- As posted but testing directly after choice

CHOICE /C YN /N /T 10 /D Y /M "Use Large Parts? -> Press 'Y' for Yes | 'N' for No
IF ERRORLEVEL 1 SET CAMFORLARGEPARTS=YES
IF ERRORLEVEL 2 SET CAMFORLARGEPARTS=NO
ECHO.
ECHO The value set for variable CAMFORLARGEPARTS is %CAMFORLARGEPARTS%
CHOICE /C YN /N /T 10 /D Y /M "Use Large Parts? -> Press 'Y' for Yes | 'N' for No

IF ERRORLEVEL 1 SET CAMFORLARGEPARTS=YES
IF ERRORLEVEL 2 SET CAMFORLARGEPARTS=NO
ECHO.
ECHO The value set for variable CAMFORLARGEPARTS is %CAMFORLARGEPARTS%

echo.&ECHO Now testing ERRORLEVEL changes with intervening ECHO

call :seterr 8
ECHO ERRORLEVEL is %errorlevel%
ECHO ERRORLEVEL is %errorlevel%
echo.&ECHO But testing ERRORLEVEL changes with intervening CALL ECHO
CALL ECHO ERRORLEVEL is %%errorlevel%%
ECHO ERRORLEVEL is %errorlevel%
echo.&ECHO But testing ERRORLEVEL changes with intervening different CALL ECHO
call :seterr 7
CALL ECHO ERRORLEVEL is %errorlevel%
ECHO ERRORLEVEL is %errorlevel%

echo.&ECHO Now testing ERRORLEVEL changes with intervening SET

call :seterr 6
ECHO ERRORLEVEL is %ERRORLEVEL%
SET zz=61
ECHO ERRORLEVEL is %errorlevel%

echo.&ECHO Now testing ERRORLEVEL changes with intervening SET /A

call :seterr 5
ECHO ERRORLEVEL is %ERRORLEVEL%
SET /a zz=616
ECHO ERRORLEVEL is %errorlevel%

PAUSE
GOTO :eof

:seterr
EXIT /B%1

Result:

Test results

So there appears to be something wrong with OP's test scenario...and I think I see it.

The code manipulates and displays CAMFORLARGEPARTS but the display shown is of SOLIDCAMFORLARGEPARTS.

Solution 4:[4]

Try:

IF %ERRORLEVEL% EQU 1 SET CAMFORLARGEPARTS=YES
IF %ERRORLEVEL% EQU 2 SET CAMFORLARGEPARTS=NO

IF ERRORLEVEL 1 checks if the ERRORLEVEL is equal to 1 OR greater than one, this is problematic because if ERRORLEVEL is 2 then that will also be greater than one.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Compo
Solution 2
Solution 3 Magoo
Solution 4