Home > Net >  Batch - return value from inside a loop
Batch - return value from inside a loop

Time:09-29

I have the following Problem:

I have 2 functions/labels called STARTERand Get_age. The Get_age function stores ages and names in some related variables and shall return the age of the person i passed to it (passed the name). But the variable which shall store the return value -> means !arr[%%i].age!seems to be empty all the time. I think this is may of the (ENDLOCAL ...) block.

What confuses me too: if i only want to return the %%i inside the (ENDLOCAL ...) block it works fine, but when there are some !exclamation marks! the variable seems to get empty.

How can i now return the age easily without bloating the code? PS: This piece of code is only a small example to give a better view on it.

Thank´s a lot

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
REM FUNCTION WHICH ASKS STORES A NAME AND ASKS FOR ITS AGE
:STARTER
setlocal
set "person=Niels"
call :Get_age "%person%" "readback"
echo %person% is -%readback%- years old.
pause
exit /b 0

REM FUNCTION WHICH RETURN THE AGE TO THE GIVEN NAME
:Get_age
setlocal
set "searchName=%~1"
set "retVal=%~2"
set "arr[0].name=Niels"
set "arr[0].age=5"
set "arr[1].name=Julia"
set "arr[1].age=2"
set "arr[2].name=Claus"
set "arr[2].age=9"
set "arr_size=2"
REM Go through the arr and return the age to the given name
for /l %%i in (0 1 %arr_size%) do (
    if "!arr[%%i].name!" equ "%searchName%" (
        (ENDLOCAL
            set %retVal%=!arr[%%i].age!
        )
    )
)
exit /b 0

CodePudding user response:

Perhaps this structure, which enables delayed expansion only when needed, and ends it again as soon as it has no further purpose, will work better for you:

@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion

Rem Stores a name, determines their age and returns it.

Set "person=Niels"
Call :Get_Age "%person%" "readback"
Echo %person% is -%readback%- years of age.
Pause
Exit /B 0

:Get_Age
Set "arr[0].name=Niels"
Set "arr[0].age=5"
Set "arr[1].name=Julia"
Set "arr[1].age=2"
Set "arr[2].name=Claus"
Set "arr[2].age=9"

Set "arr_size=2"

For /L %%G In (0,1,%arr_size%) Do (
    SetLocal EnableDelayedExpansion
    If /I "!arr[%%G].name!" == %1 (
        For %%H In ("!arr[%%G].age!") Do (
            EndLocal
            Set "%~2=%%~H"
        )
    ) Else EndLocal
)
GoTo :EOF

CodePudding user response:

You could store the value and return it after the loop.

set "found="
for /l %%i in (0 1 %arr_size%) do (
    if "!arr[%%i].name!" equ "%searchName%" (
       set "found=!arr[%%i].age!"
    )
)
(
    ENDLOCAL
    set "%retVal%=%found%"
)
goto :eof
  • Related