无忧启动论坛

标题: {已解决}批处理多选菜单问题 [打印本页]

作者: 2011qx    时间: 2016-12-11 21:59
标题: {已解决}批处理多选菜单问题
本帖最后由 2011qx 于 2016-12-20 17:30 编辑

鉴于用 set /p ID=
if "%id%"=="1"
方式 最大的缺点就是输入英文的双引号“ " ”或是拖拽带空格的文件到窗口都会退出,

谢谢各位帮忙,搞定了

在次说声谢谢
作者: 不知    时间: 2016-12-11 23:00
本帖最后由 不知 于 2016-12-12 11:10 编辑

问题2:
可以用if defined (变量名) (命令)



比如说:
在菜单选择时
set menu1=[随便的字符串(无空格)]
在后面用
if defined menu1 [处理命令]
缺点是菜单只能选一次,如果要处理多次可以用
if defined menu1 if %menu1%==[特定的字符串(无空格)]
————————————————————————————————————-
菜单示例:

@echo off

rem 清空以前的选择。
for /L %%i in (1,1,20) do if defined menu%%i set menu%%i=


rem 此处显示菜单
:menu
echo 1.menu1 2.menu2 3.menu3 4.menu4 ...

set /p id=请输入数字(输入Y执行,输入N+数字取消选择):
if not defined id (
echo 请选择菜单
cls
goto :menu
)
if defined id (
if /I %id:~,1%==N set menu%id:~1%=
set menu%id%=1
set id=
if /I not  %id%==Y  goto :menu

)


rem 此处添加处理
for /L %%i in (1,1,20) do if defined menu%%i (
echo 你选择了menu%%i
call :menu%%i
)


goto :EOF

rem 子菜单区

:menu1
echo 1
pause
goto :EOF

:menu2
echo 2
pause
goto :EOF

:menu3
echo 3
pause
goto :EOF

:menu4
echo 4
pause
goto :EOF

rem 更多子菜单....



菜单多选.7z (475 Bytes, 下载次数: 11)








作者: slore    时间: 2016-12-11 23:04

  1. @echo off

  2. set OPT_CHECKED_ALL=0
  3. call :OPT_CHECKED_SET ○

  4. :CHOOSE_MENU
  5. set option=
  6. set fixed_option=
  7. echo ===Menu===
  8. echo =%OPT1_CHECKED% 1. 选项1=
  9. echo =%OPT2_CHECKED% 2. 选项2=
  10. echo =%OPT3_CHECKED% 3. 选项3=
  11. echo =%OPT4_CHECKED% 4. 选项4=
  12. echo =%OPT5_CHECKED% 5. 全选/取消选择=
  13. echo =%OPTOK_CHECKED% OK. 下一步=
  14. set /p option=请选择功能,选择完成后请输入OK进行下一步:

  15. rem 替换引号为空
  16. if not "x%option%"=="x" set fixed_option=%option:"=%

  17. if "x%fixed_option%"=="x" (
  18.   goto :CHOOSE_MENU
  19. )

  20. if "x%fixed_option%"=="x1" (
  21.   if [%OPT1_CHECKED%]==[○] (set OPT1_CHECKED=●) else (set OPT1_CHECKED=○)
  22.   goto :CHOOSE_MENU
  23. )
  24. if "x%fixed_option%"=="x2" (
  25.   if [%OPT2_CHECKED%]==[○] (set OPT2_CHECKED=●) else (set OPT2_CHECKED=○)
  26.   goto :CHOOSE_MENU
  27. )
  28. if "x%fixed_option%"=="x3" (
  29.   if [%OPT3_CHECKED%]==[○] (set OPT3_CHECKED=●) else set OPT3_CHECKED=○
  30.   goto :CHOOSE_MENU
  31. )
  32. if "x%fixed_option%"=="x4" (
  33.   if [%OPT4_CHECKED%]==[○] (set OPT4_CHECKED=●) else set OPT4_CHECKED=○
  34.   goto :CHOOSE_MENU
  35. )
  36. if "x%fixed_option%"=="x5" (
  37.   if %OPT_CHECKED_ALL%==0 (
  38.     call :OPT_CHECKED_SET ●
  39.     set OPT_CHECKED_ALL=1
  40.   ) else (
  41.     call :OPT_CHECKED_SET ○
  42.     set OPT_CHECKED_ALL=0
  43.   )
  44.   goto :CHOOSE_MENU
  45. )
  46. if /i "x%fixed_option%"=="xOK" (
  47.   goto :MAIN
  48. )

  49. goto :CHOOSE_MENU

  50. :MAIN
  51. if %OPT1_CHECKED%==● echo 你选择了1
  52. if %OPT2_CHECKED%==● echo 你选择了2
  53. if %OPT3_CHECKED%==● echo 你选择了3
  54. if %OPT4_CHECKED%==● echo 你选择了4
  55. pause
  56. goto :EOF

  57. :OPT_CHECKED_SET
  58. for /l %%i in (1,1,4) do set OPT%%i_CHECKED=%1
  59. goto :EOF


复制代码


如果启用变量延时的话,代码可以精简些,不过作为例子这样容易懂些。
作者: 2011qx    时间: 2016-12-12 11:48
慢慢研究下谢谢
作者: 2011qx    时间: 2016-12-14 10:53
不知 发表于 2016-12-11 23:00
问题2:
可以用if defined (变量名) (命令)

谢谢你的帮助,我现在在吧批处理做完,做玩后就来专搞这2个问题
作者: 2011qx    时间: 2016-12-16 09:58
slore 发表于 2016-12-11 23:04
如果启用变量延时的话,代码可以精简些,不过作为例子这样容易懂些。

你这个好像只能选一个啊
作者: 2011qx    时间: 2016-12-16 16:03
slore 发表于 2016-12-11 23:04
如果启用变量延时的话,代码可以精简些,不过作为例子这样容易懂些。

你这个菜单还是不错的哈哈谢谢,可以帮我看看choice菜单形式的不,这种不会输入特殊字符退出
作者: 不知    时间: 2016-12-18 12:30
变量表达式等号的作用。



作者: slore    时间: 2016-12-18 16:34
本帖最后由 slore 于 2016-12-18 16:46 编辑
  1. rem 替换引号为空
  2. if not "x%option%"=="x" set fixed_option=%option:"=%
复制代码


输入单个引号程序退出的原因是,这里用了比较。本来是应对啥都不输入直接回车的情况,结果输入"比较语句就错了,还轮不到替换。

解决方法有2个,第一个方法:给option设置初始值,这样就不用判空了,直接判断是初始值再回到菜单。
第二个方法:判断是否有输入改为define来判断,不牵扯获取option的值,这样不会引用option的内容"导致语法错误。
  1. rem 替换引号为空
  2. if DEFINED option set fixed_option=%option:"=%
复制代码


另外使用变量延时简化判断的代码完整如下:
  1. @echo off
  2. SETLOCAL  ENABLEDELAYEDEXPANSION

  3. set OPT_CHECKED_ALL=0
  4. call :OPT_CHECKED_SET ○

  5. set MAX_OPT=4

  6. :CHOOSE_MENU
  7. set option=
  8. set fixed_option=
  9. echo ===Menu===
  10. echo =%OPT1_CHECKED% 1. 选项1=
  11. echo =%OPT2_CHECKED% 2. 选项2=
  12. echo =%OPT3_CHECKED% 3. 选项3=
  13. echo =%OPT4_CHECKED% 4. 选项4=
  14. echo =%OPT5_CHECKED% 5. 全选/取消选择=
  15. echo =%OPTOK_CHECKED% OK. 下一步=
  16. set /p option=请选择功能,选择完成后请输入OK进行下一步:

  17. rem 替换引号为空
  18. if DEFINED option set fixed_option=%option:"=%

  19. if "x%fixed_option%"=="x" (
  20.   goto :CHOOSE_MENU
  21. )

  22. set /a opt_n=0
  23. :OPT_CHECK_LOOP
  24. if "x%fixed_option%"=="x%opt_n%" (
  25.   if [!OPT%opt_n%_CHECKED!]==[○] (set OPT%opt_n%_CHECKED=●) else (set OPT%opt_n%_CHECKED=○)
  26.   goto :CHOOSE_MENU
  27. )
  28. set /a opt_n+=1
  29. if %opt_n% GTR %MAX_OPT% goto :OUT_OPT_CHECK
  30. goto :OPT_CHECK_LOOP


  31. :OUT_OPT_CHECK
  32. if "x%fixed_option%"=="x5" (
  33.   if %OPT_CHECKED_ALL%==0 (
  34.     call :OPT_CHECKED_SET ●
  35.     set OPT_CHECKED_ALL=1
  36.   ) else (
  37.     call :OPT_CHECKED_SET ○
  38.     set OPT_CHECKED_ALL=0
  39.   )
  40.   goto :CHOOSE_MENU
  41. )
  42. if /i "x%fixed_option%"=="xOK" (
  43.   goto :MAIN
  44. )

  45. goto :CHOOSE_MENU

  46. :MAIN
  47. if %OPT1_CHECKED%==● echo 你选择了1
  48. if %OPT2_CHECKED%==● echo 你选择了2
  49. if %OPT3_CHECKED%==● echo 你选择了3
  50. if %OPT4_CHECKED%==● echo 你选择了4
  51. pause
  52. goto :EOF

  53. :OPT_CHECKED_SET
  54. for /l %%i in (1,1,%MAX_OPT%) do set OPT%%i_CHECKED=%1
  55. goto :EOF
复制代码

作者: devilma    时间: 2016-12-18 17:39
不错的说,学习了。。。。
作者: 2011qx    时间: 2016-12-20 17:27
slore 发表于 2016-12-18 16:34
输入单个引号程序退出的原因是,这里用了比较。本来是应对啥都不输入直接回车的情况,结果输入"比较语 ...

英文双引号问题搞定了, 利用了转译符  ……就可以了
作者: uJtzY514    时间: 2017-1-11 20:06
我依旧站在这古老的战场上,糊了一把乱风向。




欢迎光临 无忧启动论坛 (http://bbs.wuyou.net./) Powered by Discuz! X3.3