Posted by: Eric Witham
AS/400, IBM i
Happy Friday Everyone!
(Originally I meant last Friday, when I started writing this)
One of the projects on my Side List is to convert the User Menus on our system from either a DSPF type or a MNUDDS/MNUCMD type member to a UIM Menu. I must say, ever since I started modifying UIM Menus as small service requests, I’ve always been intrigued by them. They’re straight forward and allow you a great opportunity to create help text in a very easy and efficient manner.
The only issue is that if you don’t know how to write one, it’s very frustrating locating all the exact pieces that need to be in place. This post is going to save you all that time spent investigating and trying various things out.
First things first, this is a Panel Group, so this is going to feel a little bit different the syntax you typically write on your AS/400. To me, it feels a little bit more like HTML just because of the fact that you have to use tags. So let’s begin, shall we?
Navigate yourself to your PDM File & Library, hit F6 to create a new Member with the type MENU.
When it opens up of course you’ll have a blank slate to work with. Since the member is waiting for you to give it life, you must first acknowledge its existence by giving it a Member Header. All commented source needs to begin with a period (.) and and asterisk (*).
The next thing we have to do is begin the panel group code. We start by entering the tag PNLGRP (and put a colon (:) before the P in PNLGRP), . as you can see in the below screen shot. This is done merely to start the Panel Group. The next statement will add your Company’s name to the bottom of the menu on line 24 of the screen.
One important thing to remember is that before the tag name is entered a colon (:) is required and after the tag a period (.) is required as well.
The next tag after that is the variable command that allows you to set up the name of the Menu on the top right-handside of the screen. The keyword ZMENU retrieves the member name and uses it as the name of the menu.
Now let’s set up the function keys.
Tag :KEYL opens the section to definethe List of Function Keys. Now, if you notice, i didn’t put the period until after the 2nd line. This is because the line continues and the compiler picks it up. It looks at the whole string and acknowledges it accordingly. The :KEYL gives the block of menu keys a name to reference. Take note that we are using the name menukeys and setting up the help for the block in keyl. A lot of entry here refers to to another place in the member. I
For each Function Key you want to define, you must have 4 lines in place all under 1 tag named :KEYI, or Key Item, in order to describe the key. Think of it as a mutated D-Spec.
The KEY code will setup which CF Key you are doing. The HELP key will indicate the help panel associated with this key. The ACTION will obviously indicate the Action to be taken once this key is pressed and lastly, you’ll need to put Text for this command key. This information gets left-justified as shown below.
For F3 & F12 you will need to add an additional keyword & initialize it to No by typing VARUPD=NO. This keyword specifies whether dialog variables are to be updated when the user presses the function key. All of the keys and reserved keywords in there are ready for use when you input the text. Once you’re done with the function key definitions, you end the block with an :EKEYL.
Another important and pretty cool thing you can do in these menus is setup and customize the Help. In this section when you specify the keyword HELP=helpf1, you are pre-defining the help text block. That name, helpf1, or whatever you end up using for the name there, will be used at the end of this member which will be linked to the help text we create. Just bare with me and we’ll get there.
* BE AWARE OF WHERE THE PERIOD FALLS FOR EACH OF THE DEFINED FUNCTION KEYS *
So far so good eh? Looks like we’re moving right along. Next on the agenda is to define the Menu Panel and the Menu Area. Start by adding the tag to define the Panel by typing a colon (:) then PANEL as 1 word and set the NAME to mnupnl since the member we are creating is a Menu Panel, i.e. mnupnl. (I had to separate : and the P or else it would’ve looked like this :P) We set up the name of the block we are going to use for Help Text. The keys we setup earlier was in the block named menukeys. When the user hits ENTER, if there is no option taken, we send the message CPD9816 (because here we are monitoring for it) which has the text, “Type option number or command.” The keyword PANELID specifies what text to display as the identifier for this panel, which appears in blue at the top-left corner of the screen. Since we’ve specified ZMENU, the menu name appears there. Finally, the TOPSEP=SYSNAM keyword specifies that the system name is to be used as a separator at the top of the panel-meaning that the system name will appear on the menu to the right on the line after the menu title.
Now that we’ve defined the menu, we have to setup the Menu Area. The DEPTH=’*’ keyword indicates that the menu area will have as many lines as are left after allocating space for the title, function keys, command line, message line, and so on. You can also supply a specific number of lines, but I can’t see why you would. Using the keyword & value SCROLL=YES is what makes this a rolling menu, meaning you can page down for more options once you setup multiple options that require a second page. The bottom separator BOTSEP keyword indicates what to use at the bottom of the menu area to separate it from the command line. Entering SPACE will simply leave a blank line at the bottom. Finally, the TOPINST. along with Select one of the following: will place the text on the top of the screen above the menu options and below the menu definition.
Now we finally get to the setting up of the actual options. I’m telling you, once you get passed the initial part of creating the actual menu for the first time, creating menus by copying & modifying is the easiest thing in the world.
In order to setup the menu options you really only need 4 lines:
Line 1 – The Menu Item Tag. This tag along with the keyword OPTION and the number of the option, sets up a menu item, or menu option.
Line 2 – The ACTION keyword. This runs a command to be processed once the option has been entered. The command string must always start with CMD and must always be in single quotes. Another important thing to remember is that when you need to use parameters in your call statements, use 2 single quotes here for every single quote you would use if you were putting that call statement into a CL program.
Line 3 – The name of the Help block that will be used to describe Option 1 when the user hits F1 for Help on the menu. Please Note that the value must be in single quotes and at the end of this line is where the period must go.
Line 4 - This is where you enter in the text for the menu option. No need to put a number with a period, just left justify your text and enter it in. For each of these values, I believe 55 positions is the maximum length you can use.
If you notice in the below screen shot, i have highlighted the text in options 3-7 in purple. I did this because I wanted to let the user of this menu know that these options are the only ones on the menu that require a specific action to be done before taking those options. In order to make everything line up, I’ve placed a Green Attribute Hex-character before the other menu option’s text.
For information on changing the color of your source, please review my previous article:
We finish off the :MENU block that was created on Line# 90 in the above screen shot by closing out with an :EMENU tag on line 143 in the below screenshot.
At long last, we have the 2 final pieces for the Main Panel group: The Command Line & the End Panel Group Tag.
Enter in the command :CMDLINE along with the keyword SIZE= and use the value LONG if you want the command line to be a long field, as seen via STRPDM, or SHORT if you want a small field for the option to be taken. No command line entry is allowed if you have it set to SHORT.
Also, we finally get to close the Panel Group by using the command :EPANEL. Think of it like this. If you have a /FREE specified in your free-form program, then you’re going to need an /END-FREE to close out the block, right? Same thing.
Well here we are, finally at the end of what needs to be done. This part, I’m going to go through a little less in-depth than i have with the previous items. I’ll explain the instructions based on the Statement Numbers.
The help area is pretty straight-forward and easy to do.
Line Numbers 156.00 – 162.00
Start by setting up the :HELP block and link the command key block from earlier in the source to the function keys. We named the function keys KEYL so we have that module name be the value for the Help Name. The text “Function Keys – Help” I believe is only there to indicate that this block of Help Text refers to the Function Keys. On 161.00 the :XH3 displays this text as a Starting Group of help to fall underneath it, kind of like a Title with chapters underneath it. At the end i’ll show you the completed Menu & Help screens. Don’t forget to close out the Help Block with :EHELP.
Line Numbers 164.00 – 171.00
This next block of code writes the Help Text for Command Function 1. So if the user puts their cursor over option 1 and hits F1 a small window will be displayed showing the text on lines 168.00 & 169. The value we use for the Name of the help is helpf1 which was setup on line 36.00 in the Key Items block for Key F1. We’re using the :PARML keyword because we’re using the F1=Help as a parameter list. Once hit and the cursor is on that option it displays the text and there you go. Close out the block by putting an :EPARML & :EHELP.
As you can see in the rest of the Source member, I added in all the Help text I could, following the rules of using the keywords, module names and wrote as much help text as I could to assist the user in whatever He or She may need.
Line Number 389.00
Ends the Panel Group of the Entire Member. If you recall in line number 17.00 we started this with a :PNLGRP. Now that we’re done, we close it off and Compile the hell out of it.
So here it is, the End Result, your Menu…
And here is what happens when you put the Cursor on option 3 and hit F1…
I hope I have helped some of you get a better understanding on UIM Menus, how to write them, how to understand them, and most of all, how easy it is to come up with a Professional looking menu that scrolls instead of having to deal with DSPF menus with random options on the side of the screen or hidden options that some users know about. One of my side projects at my current position is to convert all menus to UIM menus in order to clean things up and make the system a little bit more organized and have a professional look for the users.
There is a decent amount of information out there that can help you understand UIM menus on a more technically instructed level, but as I said previously, I am no expert in UIM Menus. I found out how to do all this by Research, Trial & Error. I figured it might be nice for someone, who has no idea how to do this, to wow their bosses and higher ups on how great and efficient they can make their menus. Here are a few articles I found that helped me along the way and one that I actually just found a few minutes ago. The last one is pretty good and it looks like it’s more current than the first two:
Create IBM-Style Rolling Menus with UIM
Written by Ernie Malaga
Wednesday, June 30, 1993
Dynamic UIM Menu Help
Written by Mike Faust
Wednesday, December 14, 2011
Create Better Menus with UIM
Written by Scott Klement
Thursday, August 11, 2011