Не объявляется переменная

Foxik

Пользователь
Сообщения
41
Реакции
25
где ошибка в сценарии? Почему не объявляются переменные cnt и summ?
CMD/BATCH:
@echo off
rem SetLocal EnableExtensions EnableDelayedExpansion
Echo List Local users:

for /f "usebackq tokens=2 delims==" %%a in (`WMIC UserAccount Where "LocalAccount=True" Get Name /Format:List`) do (

set /a cnt+=1
set "User_%cnt%=%%a"
set "summ=%summ%%cnt%"
ECHO %cnt%. %%a
)
echo %summ%
 
Последнее редактирование модератором:

Dragokas

Very kind Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,630
Реакции
6,088
Способ 1.
1) *Вам нужно заменить %cnt% на !cnt!
2) снять с комментария 2-ю строку с директивами, т.к. EnableDelayedExpansion включает режим отложенного раскрытия переменных (разрешение на использование тех самых знаков !!)
3) Что Вы хотите получить в переменной summ ?

* Все команды, выполняемые внутри блока (цикл, скобки или однострочные команды) изменяют переменные среды только после выхода из данного блока.
Чтобы получить актуальное значение переменной внутри этого же блока, нужно использовать механизм, указанный мною в пп.1,2.
При этом не важно, где было произведено изменение значения переменной (внутри блока, через переход в подпрограмму или внешним окружением (например, псевдослучайное число, текущая дата/время). Все они при входе в блок команд запоминаются и "замораживаются".

Использование режима DelayedExpansion имеет одну неприятную особенность: нельзя работать со знаками ! как со строкой (при этом знаки ! в выводе других команд также "глотаются").
Поэтому иногда имеет смысл отключать или вовсе не использовать этот режим.

Способ 2.
Раскрывать значение переменной в другом процессе CMD:
1) заменить тело цикла на код с использованием команды SET (при этом знаки % следует удвоить):

CMD/BATCH:
set /a cnt+=1
call set "User_%%cnt%%=%%a"
call set "summ=%%summ%%%%cnt%%"&rem здесь что писать не знаю; жду пояснения.
call ECHO %%cnt%%. %%a
 
Последнее редактирование:

Foxik

Пользователь
Сообщения
41
Реакции
25
Спасибо, разобрался, все поправил, все работает...
Вот итог:
CMD/BATCH:
@echo off
Setlocal EnableDelayedExpansion
Echo List Local users:
for /f "usebackq tokens=2 delims==" %%a in (`WMIC UserAccount Where "LocalAccount=True" Get Name /Format:List`) do (
set /a cnt+=1
set "User_!cnt!=%%a"
set "summ=!summ!!cnt!"
ECHO !cnt!. %%a
)
Choice /C %summ% /M "choice users:"

Переменная summ нужна была для параметра команды CHOICE... хотя теперь это и так понятно:rolleyes:
Теперь еще кто-нибудь, также доходчево объяснил бы про EnableExtensions:whistle:
 
Последнее редактирование модератором:

Dragokas

Very kind Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,630
Реакции
6,088
Переменная summ нужна была для параметра команды CHOICE... хотя теперь это и так понятно
Оригинально придумано :)
Теперь еще кто-нибудь, также доходчево объяснил бы про EnableExtensions
http://safezone.cc/threads/cmd-setlocal-i-rasshirennaja-obrabotka-komand.22629/Другими словами, если я сделаю вот так:
Код:
reg add "HKCU\Software\Microsoft\Command Processor" /v EnableExtensions /t REG_DWORD /d 0 /f
Ваш последний скрипт перестанет работать ;)
 
Последнее редактирование:

Dragokas

Very kind Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,630
Реакции
6,088
Точнее /X:ON или /E:ON
или посмотреть внимательно на Ваш первый скрипт.
 

Foxik

Пользователь
Сообщения
41
Реакции
25
Вот еще вариант без Setlocal:
CMD/BATCH:
@echo off
Echo List Local users:
for /f "usebackq tokens=2 delims==" %%a in (`WMIC UserAccount Where "LocalAccount=True" Get Name /Format:List`) do CALL:CREATE_CMD %%a
Choice /C %summ% /M "choice users:"
call set choi_usr=%%user_%errorlevel%%%

echo %choi_usr%
pause

goto:eof
:CREATE_CMD
set /a cnt+=1
set User_%cnt%=%1
set summ=%summ%%cnt%
ECHO %cnt%. %1
 
Последнее редактирование модератором:

Dragokas

Very kind Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,630
Реакции
6,088
Foxik, да можно и так. Но для небольших конструкций слишком "расточительно" по объему кода.
Кроме того, если Вас заинтересует скорость работы этих 3-х вариантов, то они соотносятся примерно так:

1) точка отсчета затраченного времени - раскрытие значения через %%
2) через !! ~ 2,5 раза медленнее
3) через подпрограмму ~ 42 раза медленнее
4) через call set ~ 60 раз медленнее

Для конкретного кода, конечно, не имеет значения, а вот для пакетной обработки OVER 100 строк уже чувствуется (особенно на слабых машинах).

P.S. Саму команду SetLocal указываю всегда, ибо после выхода из батника все измененные переменные окружения автоматически обнуляются
(либо это можно сделать еще раньше - командой EndLocal)
или посмотреть внимательно на Ваш первый скрипт.
т.е. Вы можете указывать SetLocal EnableExtensions всегда и тогда Ваш скрипт не будет зависеть от указанного мною в реестре твика.
 
Последнее редактирование:
Сверху Снизу