@ECHO Off
SETLOCAL
set /p "startdate=Start Date(yyyymmdd):"
set /p "finishdate=Finish Date (yyyymmdd):"
echo %startdate%
echo %finishdate%
IF %finishdate% lss %startdate% ECHO Invalid DATE range&GOTO :eof
echo start loop
FOR /L %%c IN (%startdate%,1,%finishdate%) DO (
FOR /F %%y IN ('set /a inputan^=%%c %% 100') DO IF %%y lss 32 IF %%y gtr 0 (
echo %%c
set /a inputan=%%c
call :test_loopong.bat %%c
)
)
GOTO :EOF
:test_loopong.bat
ECHO IN test_loopong : %%1=%1 inputan=%inputan%
GOTO :eof
I changed the variable names so that they are maintainable, 'though I've no idea what inputan
means.
Added invalid date-range check.
Note syntax of set /p
Forget for the moment what for...%%y...
does.
I used a set /a
since %%c
must be numeric.
Use set "var1=value"
for setting STRING values - this avoids problems caused by trailing spaces.
I converted test_loopong.bat
to an internal subroutine (call :name) for demonstration purposes to avoid having to generate another file.
I'm having that subroutine simply display the value of the variable inputan
and the parameter %1
. %%c
can be delivered as a parameter to the subroutine (be it internal or external) but your syntax would appear to omit the parameter because of the delayed expansion trap - %var% will be replaced by the value of var
at the time the outer loop (for...%%c
) is encountered.
Now the for...%%y
jiggery-pokery.
The command set /a inputan=%%c % 100
would set inputan
to %%c mod 100. There's no importance about the variable name - that one's about to be assigned a different value again in a couple of lines.
When used in a for /f
, batch will execute the set/a
command and echo
the result to the metavariable %%y
.
However, =
and %
are special characters and need to be "escaped" (interpreted without their special meaning). Th escape character for most specials is caret (^
) but for %
is %
itself.
The result of the calculation is assigned to %%y
and we can then test that %%y
is lss 32
- Less than 32, and also it is gtr 0
- Greater than 0. Only then do we call
test_loopong.bat. This eliminates most non-dates
If you don't want to skip the non-dates, then remove the for...%%y
line and delete one of the )
lines.
--- further thoughts ----
Suppressing the days 32..99 & 00 really only does half the job. Much better if we suppress months 13..99 & 00. The revision then would be (presenting just the main loop, minus the frippery)
FOR /L %%c IN (%startdate%,1,%finishdate%) DO (
FOR /F %%e IN ('set /a inputan^=%%c %% 10000') DO IF %%e lss 1232 IF %%e gtr 100 (
FOR /F %%y IN ('set /a inputan^=%%c %% 100') DO IF %%y lss 32 IF %%y gtr 0 (
echo %%c
set /a inputan=%%c
call :test_loopong.bat %%c
)
)
)
Same principle, just dealing with months in place of days.
One slight problem with this method is that it's as slow as a wet week.
So - a different approach
SET /a yyyy=%startdate:~0,4%
SET /a mm1=1%startdate:~4,2%
SET /a dd1=1%startdate:~-2%
:loop2
SET /a inputan=%yyyy%0000+%mm1%00+dd1-10100
IF %inputan% gtr %finishdate% GOTO :eof
CALL :test_loopong.bat %inputan%
SET /a dd1+=1
IF %dd1% leq 131 GOTO loop2
SET /a dd1=101&SET /a mm1+=1
IF %mm1% leq 112 GOTO loop2
SET /a mm1=101
SET /a yyyy+=1
GOTO loop2
This sets yyyy
to the year and mm1
/dd1
to 100+(month/day). 100+
needs to be done since batch regards a numeric string that starts 0
as
octal hence August and September cause problems.
So - calculate inputan
by tringing 4 0
s to yyyy
, adding 100*mm1 and dd1, then subtracting 10100 since mm1 is mm+100 and dd1 is dd+100.
If the resultant inputan
is greater than the finish date, end the routine.
Test using inputan
.
Next day - add 1 to dd1
.
If the result is less than or equal to 131, we're fine.
Otherwise set dd1
to 101
and increment the month
Same recipe for mm1
, limit is 112
and bump the year if required.
---- Further revision to deal with non-dates 31st Apr, Jun, Sep, Nov and Feb (include leap years) ---
@ECHO Off
SETLOCAL
set /p "startdate=Start Date(yyyymmdd):"
set /p "finishdate=Finish Date (yyyymmdd):"
echo %startdate%
echo %finishdate%
IF %finishdate% lss %startdate% ECHO Invalid DATE range&GOTO :eof
echo start loop
GOTO ver2
FOR /L %%c IN (%startdate%,1,%finishdate%) DO (
FOR /F %%e IN ('set /a inputan^=%%c %% 10000') DO IF %%e lss 1232 IF %%e gtr 100 (
FOR /F %%y IN ('set /a inputan^=%%c %% 100') DO IF %%y lss 32 IF %%y gtr 0 (
echo %%c
set /a inputan=%%c
call :test_loopong.bat %%c
)
)
)
GOTO :EOF
:ver2
SET /a yyyy=%startdate:~0,4%
SET /a mm1=1%startdate:~4,2%
SET /a dd1=1%startdate:~-2%
:loop2
SET /a inputan=%yyyy%0000+%mm1%00+dd1-10100
IF %inputan% gtr %finishdate% GOTO :eof
CALL :test_loopong.bat %inputan%
SET /a dd1+=1
SET /a inputan=yyyy %% 4
IF %mm1%==102 IF %dd1% gtr 129 (GOTO nextmonth) ELSE IF %inputan% neq 0 IF %dd1%==129 GOTO nextmonth
FOR %%e IN (104 106 109 111) DO IF %%e131==%mm1%%dd1% GOTO nextmonth
IF %dd1% leq 131 GOTO loop2
:nextmonth
SET /a dd1=101&SET /a mm1+=1
IF %mm1% leq 112 GOTO loop2
SET /a mm1=101
SET /a yyyy+=1
GOTO loop2
GOTO :eof
:test_loopong.bat
ECHO IN test_loopong : %%1=%1 inputan=%inputan%
GOTO :eof