0

I have stripped my problematic code down to the problematic lines. Why the first echo works and the second one does not work?

setlocal enabledelayedexpansion
set /a r=19
set blocks=MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM

for /L %%a in (-%r%,1,%r%) do (
   set /a w2=r
   :: This works
   set line=!blocks:~0,%r%!
   echo( !line!

   ::This does'nt work
   set line=!blocks:~0,!w2!!   
   echo( !line!
)  
exit /b 

EDITED: I have kept on trying and this line works:

call set line=%%blocks:~0,!w2!%%

Now the question is : could someone please explain to me WHY I must use call?

Antoni Gual Via
  • 634
  • 1
  • 6
  • 12

2 Answers2

1

You should use the r variable directly with percent expansion, as long as the value doesn't change inside the loop.

set line=!blocks:~0,%r%!

Or use a helper loop for other variables.

 for /F "tokens=*" %%H in ("!w2!") do (
      set line=!blocks:~0,%%H!
   )
jeb
  • 70,992
  • 15
  • 159
  • 202
1

The possible methods to expand a variable with !delayed expansion! using other variables for substring position or length, that may change inside a code block, are described at this post:

To get the value of a substring when the index changes inside FOR/IF, enclose the substring in double percent symbols and precede the command with call. For example:

call set line=%%blocks:~0,!w2!%%

This method makes good use of the fact that call command allows to re-expand a variable enclosed in double percent-signs, as described in the second answer at this question:

The BatchLineParser:

1) Phase: Expansion of %var%...

6) Phase: If the command is CALL, start with phase 1 again.

Another way to achieve the previous process is to use an additional FOR command to change the delayed expansion of the index by an equivalent replaceable parameter, and then use the delayed expansion for the substring. This method runs faster than previous CALL:

for %%w in (!w2!) do set line=!blocks:~0,%%w!
Community
  • 1
  • 1
Aacini
  • 59,374
  • 12
  • 63
  • 94