Menu Help

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
jgregory84
Posts: 4
Joined: 13 May 2011 11:35

Menu Help

#1 Post by jgregory84 » 13 May 2011 11:43

Hello im trying to figure out if i can make a menu system for cmd on xp and newer systems.

Basically I want the menu to load up a list of my clients from a seperate text file as the choices, i also want the last choice to always be "Company Not Listed" From there if i choose the company not listed choice i want to have it prompt me with a few variable that i want it to write back to the text file. is this possible?

orange_batch
Expert
Posts: 442
Joined: 01 Aug 2010 17:13
Location: Canadian Pacific
Contact:

Re: Menu Help

#2 Post by orange_batch » 14 May 2011 01:29

Yes, but it's a fair bit of work. You should try it yourself first.

jgregory84
Posts: 4
Joined: 13 May 2011 11:35

Re: Menu Help

#3 Post by jgregory84 » 14 May 2011 21:19

Yea I have been working on it, I'm not lazy. I'm sure it is in regards to the for /f comman set but I havent been able to figure it out. Hence the asking for some assitance

orange_batch
Expert
Posts: 442
Joined: 01 Aug 2010 17:13
Location: Canadian Pacific
Contact:

Re: Menu Help

#4 Post by orange_batch » 15 May 2011 03:21

K, all you asked though was if it's possible, and didn't post any code for us to correct or suggest on. I'll just write it anyways...

Minimal error-handling, without enabledelayedexpansion:

clients.txt

Code: Select all

Microsoft
Apple
Google
Yahoo
Facebook


choose.cmd (or .bat)

Code: Select all

@echo off&echo:&color 0B&title Client Select ^& Add by orange_batch

for /f "delims=" %%x in (clients.txt) do (
set /a counter+=1
call set "array[%%counter%%]=%%x"
)
set /a counter+=1
set array[%counter%]=Company Not Listed
echo: ^> Choose from the following:
echo:
for /l %%x in (1,1,%counter%) do call echo:   %%x. %%array[%%x]%%
echo:
set /p "choice=   Input: "
echo:
call echo:   You chose %%array[%choice%]%%.
echo:

:: if %choice%==1 echo:   Do whatever for client Microsoft.
:: if %choice%==2 echo:   Do whatever for client Apple.

set /a last=%counter%,counter-=1
if %choice%==%last% (
echo: ^> Enter the name of the company to add.
echo:
set /p "new=   Input: "
echo:
type nul>clients.txt
for /l %%x in (1,1,%counter%) do call echo:%%array[%%x]%%>>clients.txt
call echo:%%new%%>>clients.txt
)

echo: ^> Press any key to exit.
pause>nul
exit


Notes for learning:
-The ^ caret character escapes individual command characters (one-time only, beware of use in variables).
-Command Prompt does not process command characters surrounded with quotation marks, so set "var=^&|" works where set var=^&| would not. There's no need to use quotes with set /p, but you wouldn't be able to see the trailing space character in the code otherwise.
-call %%variable%% is like !variable! but without delayed expansion.
-You can set multiple variables using set /a. set /a last=%counter%,counter-=1 is the same as set /a last=%counter%&set /a counter-=1.
-echo:whatever>clients.txt a single arrow mark will overwrite the target file.
-echo:whatever>>clients.txt the double arrow marks append to the target file.
-type nul>clients.txt clears a text file. echo:>clients.txt would "clear" it but leave a line return.

Bonus:
-You can write multiple commands on the same line by separating them with &.
-You can pipe the output of one command into another (that can accept it) using |, like echo:orange|set /p choice=Apple or orange?
-You can handle the success or failure of a command using && and ||, like set /a number+=22222222222&&echo:Calculation successful.||echo:Failed. Number is larger than 32-bits.. Beware that || has priority over && (like a separator) and the first-come-first-serve logic behind this. The command to do on failure will trigger if the command to do on success fails as well, like set /a number+=10&&set /a number+=22222222222||echo:Failed. Number is larger than 32-bits.. Putting || before && will trigger the && command if the || command is successful, not the first command. However, like math, you can group commands using parentheses (). For example, set /a number+=22222222222&&(echo:Calculation successful.||echo:"Calculation successful" echo failed.).

jgregory84
Posts: 4
Joined: 13 May 2011 11:35

Re: Menu Help

#5 Post by jgregory84 » 15 May 2011 10:15

umm I love you... haha that is awesome work and i thank you.

Now to build on that, I have
client.txt including all of this info so far

Code: Select all

Domain; Client Name;Phone Number
MSFT;Microsoft Corp;1234567890;
APPLE;Apple Inc;0123456789;


Im working on the script to pull the domain name using the %userdomain% variable, I am trying to compare that to the first column in the text and if not found I want it to go to a different Part of the file, where it will lead in to the menu array that you helped me with but if it does match the %userdomain% to the first column it will set the defined variables and continue on with my settings. Based off the script below does it look like i am on the right path?

again I thank you for all the help you have provided so far

Code: Select all

:1.0
For /f "tokens=1 delims=;"  %%A IN (G:\demo\Client.txt) DO IF NOT /I "%USERDOMAIN%"=="%%A" (
Goto 1.2
)
:1.1
REM.-- Auto detecting Network Information
For /f "tokens=1,2,3 delims=;"  %%A IN (G:\demo\Client.txt) DO IF /I "%USERDOMAIN%"=="%%A" (
   Set Domain=%%A
   Set Client=%%B
   Set Phone=%%C
)

Echo %domain%,%client%,%phone%
pause

orange_batch
Expert
Posts: 442
Joined: 01 Aug 2010 17:13
Location: Canadian Pacific
Contact:

Re: Menu Help

#6 Post by orange_batch » 15 May 2011 11:45

Without counters/arrays like in my above example, the 1.1 section you wrote is only going to store the last line in the text file, because each time it processes a new line (iterates), it overwrites the variables. It's not hard to change though, since they're matching arrays you still only need one counter.

As anyone does, I program differently than you, but I'm just going to modify your code for your sake.

1.0 modifications:

Code: Select all

For /f "tokens=1 delims=;"  %%A IN (G:\demo\Client.txt) DO IF /I "%USERDOMAIN%"=="%%A" goto found
goto not_found_menu
:found
echo:The userdomain matched a line in the client file. Do stuff here.

:not_found_menu
echo:The menu script from above this post.

The problem you had was, you're testing the %userdomain% variable against every domain in the clients file. Of course it's only going to match one or however many, your logic was reversed there. If it doesn't match any of them, it doesn't go to found, thus it comes upon the goto not_found_menu line.

This is also a good example of the proper (or pretty much only) way to break out of a for loop. You could do the "found" processing within the for loop too, but I would only do it if the amount of processing is limited, for the sake of convenience either way.

jgregory84
Posts: 4
Joined: 13 May 2011 11:35

Re: Menu Help

#7 Post by jgregory84 » 15 May 2011 14:30

You are amazing thank you again, now only question I think I have for now is with the original script you gave me, it seems to skip the numbers 5 and 10, but not the actual choices. I.E the 5th item in the clients.txt simply becomes choice 6. which I can live with but if you do see a fix i would be even more thankful then I already am.

orange_batch
Expert
Posts: 442
Joined: 01 Aug 2010 17:13
Location: Canadian Pacific
Contact:

Re: Menu Help

#8 Post by orange_batch » 15 May 2011 21:32

I'm not sure what you mean? Maybe you could post the part of your clients.txt having that problem.

It might be doing this if you're running that part of the script in the same session more than once. You might need to reset some variables or handle them a bit. Using setlocal and endlocal might be one solution (setlocal basically saves the current state of all variables until it encounters endlocal, at which point it reverts).

Post Reply