Force Flow
Force Flow

Reputation: 724

Using endlocal set variables in a batch file, but the variables are never available outside of the setlocal/endlocal block

I'm trying to set the value of a variable that is inside a SETLOCAL, inside a FOR loop and inside an IF statement. However, it never seems to work. I tried using a SET statement at the ENDLOCAL statement, but that doesn't seem to actually set anything. Echoing the variable after that only echos the original set value of 0.

@ECHO off

SET pathsource=K:
SET sourcefile=0
SET counter=0

SETLOCAL enableextensions enabledelayedexpansion

REM Get the newest pptx file in the specified directory. Get the filename and last modified timestamp
FOR /f "tokens=1-3,5*" %%a IN ('dir ^"%pathsource%\*.pptx^" /a-d-h-s /o-d /tw ^| find /i ^".pptx^"') DO (
    REM echo !counter!

    REM only get the first row by using a counter
    IF !counter! EQU 0 (
        REM variables are: a-date, b-time, c-am/pm, d&e-filename
        ECHO %%a %%b %%c %%d %%e

        SET sourcefile=%%d %%e
    )

    SET /A counter+=1
)


ENDLOCAL & (
    SET "sourcefile=%sourcefile%"
)

ECHO %sourcefile%

REM do other stuff with the %sourcefile% variable after this

Upvotes: 4

Views: 2843

Answers (2)

rojo
rojo

Reputation: 24466

If all you want is the name and timestamp of the newest PPTX file, your script is a lot more complicated than it needs to be. Simply scrape dir "path\*.pptx" /b /o:-d then break out of the for /f loop after the first line.

@ECHO off
setlocal

SET "pathsource=K:"

REM Get the newest pptx file in the specified directory. Get the filename and last modified timestamp
pushd "%pathsource%"
FOR /f "delims=" %%a IN ('dir "*.pptx" /b /o:-d') DO (
    set "sourcefile=%%~nxa"
    set "timestamp=%%~ta"
    goto break
)
:break

ECHO %sourcefile%
echo %timestamp%

REM do other stuff with the %sourcefile% variable after this

Upvotes: 0

Jason Faulkner
Jason Faulkner

Reputation: 6558

Because you assign the values within the Set/End Local block, any changes made within this are discarded once on the ENDLOCAL command is reached.

Just move your SETLOCAL and ENDLOCAL commands to the very top and bottom of your script respectively. This would make all assignments made within the entirety of script stick throughout.


Additionally, you don't really need the counter variable. You can just jump out of the loop after the first file is processed:

@ECHO off
REM delayed expansion not needed for the portion shown
SETLOCAL enableextensions

SET pathsource=K:
SET sourcefile=0

REM Get the newest pptx file in the specified directory. Get the filename and last modified timestamp
FOR /f "tokens=1-3,5*" %%a IN ('dir ^"%pathsource%\*.pptx^" /a-d-h-s /o-d /tw ^| find /i ^".pptx^"') DO (
    REM variables are: a-date, b-time, c-am/pm, d&e-filename
    ECHO %%a %%b %%c %%d %%e

    SET sourcefile=%%d %%e

    REM We only care about the first row
    GOTO EndLoop
)

:EndLoop
ECHO %sourcefile%

REM do other stuff with the %sourcefile% variable after this

ENDLOCAL

One last thing is you can simply your FOR syntax a bit by using native DIR and FOR variable commands:

@ECHO off
REM delayed expansion not needed for the portion shown
SETLOCAL enableextensions

SET pathsource=K:
SET sourcefile=0

REM Get the newest pptx file in the specified directory. Get the filename and last modified timestamp
CD "%pathsource%\"
FOR /f "usebackq tokens=* delims=" %%a IN (`dir "%pathsource%\*.pptx" /a-d-h-s /o-d /tw /b`) DO (
    REM Use For loop variables.
    REM Print the date/time and file name.
    ECHO %%~ta %%~a

    SET sourcefile=%%~a

    REM We only care about the first row
    GOTO EndLoop
)

:EndLoop
ECHO %sourcefile%

REM do other stuff with the %sourcefile% variable after this

ENDLOCAL

Upvotes: 3

Related Questions