Putting Power Behind PDM

General
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

Defining PDM options can save a programmer many keystrokes, yet many programmers don’t take advantage of this feature. Those who do typically define options that can be used from only one of the WRKxxxPDM displays. Here’s how to define options that can work from all WRKxxxPDM displays and that also execute more than just a single command.

Have you ever written a program or system only to find that users were not using it? Or maybe they were using it, but not as you intended it to be used? Already, memories of such projects are filling your mind, but before you let your blood pressure start to rise, stop and consider that you may be guilty of the same thing. For example, what user- defined PDM options are you using these days? Don’t tell me that IBM went to all that trouble to let you define your own options and you’re not defining them!

If I’ve figured correctly, you can define more than 1,000 PDM options. Since you can make an option do different things, depending on whether you’re accessing it from the Work with Libraries in PDM (WRKLIBPDM), Work with Objects in PDM (WRKOBJPDM), or Work with Members in PDM (WRKMBRPDM) screens, in a sense, you can define even more.

In this article, I’m going to show you how to define your own PDM options, but even more than that, I’m going to show you how to define powerful PDM options.

The Basics

From any WRKxxxPDM screen, press F16. You’ll see a list of user-defined options in a work-with panel. The list should not be empty, because IBM has already defined some options. The Work with User-Defined Options panel will allow you to create, change, and delete user-defined options.

If you’d like to try this out, press F6 and create an option that’s not already defined on your system. I’ll use SF for this example; pick something else if that option is already taken. You can use a single letter or a letter followed by either a digit or another letter.

Type WRKSPLF in the command prompt. Press Enter twice. You’ll be back to the WRK-xxxPDM screen that you left. Type SF (or whatever you named the option) in front

of an entry in the WRKxxxPDM display and press Enter. You should see the Work with Spool Files screen.

PDM Variables

Typing two characters instead of seven is nice, but that’s not all you can do. PDM has the ability to insert certain data into the command string before passing it to the operating system for execution. These data are taken from the PDM environment and are represented by the two-character substitution variables shown in Figure 1. (If you have Application Development Manager/400, there are some three-character substitution variables you can use.)

Say you want an option to let you clear a physical file member. From the WRKMBRPDM display, press the F16 key to work with user-defined options. Press F6 to create a new option. I’m going to name it Z1. (I would rather use CM, for Clear Member, but that one’s already defined on my AS/400.) If option Z1 already exists on your system, call it something else.

In the command prompt, type clrpfm and press F4. In the Physical file prompt, key in &F. In the Library prompt, key in &L. In the member prompt, key in &N. Press Enter. You’ll see the complete Clear Physical File Member (CLRPFM) command, filled in with PDM variables. Press Enter twice more to return to the Work with Members using PDM display.

If you want to test this out, create a dummy source member and populate it with a couple of dummy records. Then, key in Z1 (or whatever you called the new option) next to it and press Enter. The system will respond with an informational message telling you the member was cleared.

Typing in a two-character substitution variable is certainly easier than typing the complete Clear Physical File Member (CLRPFM) command. However, it won’t work from the WRKOBJPDM display. It won’t work from WRKLIBPDM either, but that’s OK because it shouldn’t. So, now I’ll add a little power.

Who’s Calling?

Figure 2 contains a CL program that runs correctly from any of the three PDM screens: WRKLIBPDM, WRKOBJPDM, or WRKMBRPDM. I’ll call it PDMOPT. The To execute: instructions at the beginning of the program contain the command string you’ll need to put behind a PDM option to run the PDMOPT program.

PDMOPT’s purpose is to send an error message to the users, informing them that the PDM option they selected is not allowed from the display from which they selected it. Notice that the program checks the &B PDM variable to determine from which display it was invoked, so the code includes separate areas for processing members, objects, or libraries. This program is not a finished product, but a template from which you can define a powerful PDM option.

Let’s get back to the CLRPFM problem. I want it to run from WRKMBRPDM, so I need to change the portion of the program that processes members to run the CLRPFM command that I developed earlier. First, I make a copy of the PDMOPT program and call it PDMOPTZ1. (For the complete code for the PDMOPTZ1 program, go to our Web site at http://www.midrangecomputing.com/mc/ 98/12.) I’ll modify this copy, not the template.

Figure 3 shows how I changed the code at the MEMBER label. First, I clear the file; then, I jump to the FWDMSG label to pass along the message that OS/400 sends in response. This system message should always tell the user that the file has been cleared.

However, I’d also like this to run from the WRKOBJPDM display, provided that the object selected from the list is a physical file. Figure 4 shows the routine I wrote. It checks to make sure that the selected object is a physical file and sends appropriate error messages if it isn’t. If the physical file has no members, the program informs the user. If the physical file has one member, the program clears the member. If the physical file has more than one member, the routine prompts for the name of the member to be cleared. I did

not change the program at the LIBRARY label, so the program continues to send an error message if the user uses option Z1 from the WRKLIBPDM display.

The only other task to be done is to define option Z1 to PDM. To do that, I use the command string shown in the To execute: box in Figure 2, changing the program name for PDMOPT to PDMOPTZ1. I could expand this even further (and I may do just that, one of these days.) For instance, I could allow this option to work against a logical file. If the item selected from the list were a logical file, I could clear the physical files it’s derived from. If the logical file had select or omit criteria, I could write code to delete just the records that it selects. Even OS/400 doesn’t have a command to do things like this. The point is that you can make a user-defined option do most anything you want it to.

You Can Use Your Own File

User-defined PDM options are stored in a physical file called QAUOOPT, in library QGPL. If you prefer, you can create your own PDM options file. It must have a record length of 252 bytes. The OPTION field occupies the first two bytes, and the COMMAND field occupies the remaining 250. If you run the Display File Field Description (DSPFFD) command over QGPL/QAUOOPT, you’ll see the layout. The easiest way to create your own options file is to use the Create Duplicate Object (CRTDUPOBJ) command to copy QGPL/QAUOOPT.

You can press F18 from any of the WRKxxxPDM displays to change the name of the PDM options file to use. Once you’re using your own file, you can define your own options without interfering with other PDM users.

A Few More Thoughts

I know you’re eager to get started writing a power-PDM option, but first let me point out a few things to keep in mind.

The &C variable contains the user-defined option that was executed. If that option is a single character, that character will be right justified. You can pass it into a program either right- or left-justified. To right-adjust it, enclose &C in apostrophes. To left-adjust it, omit the apostrophes, as I have done in the CALL in the To execute: instructions in Figure
2.

The &X variable contains the selected item’s text description, enclosed within apostrophes. Trailing blanks are omitted. If that description is less than 32 characters long, the text is padded to a length of 32. If the description is 32 characters long or longer, the actual text is passed, whatever its length. This is consistent with the way CALL passes character literals to a program. If you want the length to be predictable, follow the &X variable with an apostrophe, 50 blanks, a nonblank character, and another apostrophe. If you do that, you can be assured you’ll receive 50 characters of good data. Again, see how I did it in Figure 2.

The &J variable is qualified. If you use it, be sure to put it in apostrophes. The CALL statement won’t work if you don’t.

Last, you may want to pass all substitution variables into each of your power-PDM options, as I have done in Figure 2, even though few (if any) programs will need all of them. If you pass all the variables, you’ll never have to modify the option’s definition when you decide you need another variable, and you’ll always be able to start a new option from the template in Figure 2.

Have a good time, make your PDM editing more productive, and let me hear of any exciting things you do with this technique.

Ted Holt is a senior technical editor for Midrange Computing. You can reach him at holt@ midrangecomputing.com.

Reference

AS/400 Programming Development Manager User’s Guide and Reference (SC09- 1771-00, CD-ROM QBKAQK00)

Figure 1: The PDM substitution variables are the source of PDM power

/*===================================================================*/

/* To execute: */
/* */

/* CALL PGM(XXX/PDMOPT ) PARM('&A' '&B' &C '&D' + */
/* '&E' '&F' '&G' '&H' '&J' '&L' '&N' '&O' '&P' + */
/* '&R' '&S' '&T' '&U' '&V' '&W' + */
/* &X' ') */
/* */

/*===================================================================*/

/* To compile: */
/* */

/* CRTCLPGM PGM(XXX/PDMOPTxx) SRCFILE(XXX/QCLSRC) */
/* */

/*===================================================================*/

PGM PARM(&A &B &C &D &E &F &G &H &J &L &N &O +

&P &R &S &T &U &V &W &X)

DCL VAR(&A) TYPE(*CHAR) LEN(10)

DCL VAR(&B) TYPE(*CHAR) LEN(10)

DCL VAR(&C) TYPE(*CHAR) LEN(2)

DCL VAR(&D) TYPE(*CHAR) LEN(8)

DCL VAR(&E) TYPE(*CHAR) LEN(4)

DCL VAR(&F) TYPE(*CHAR) LEN(10)

DCL VAR(&G) TYPE(*CHAR) LEN(10)

DCL VAR(&H) TYPE(*CHAR) LEN(10)

DCL VAR(&J) TYPE(*CHAR) LEN(21)

DCL VAR(&L) TYPE(*CHAR) LEN(10)

DCL VAR(&N) TYPE(*CHAR) LEN(10)

DCL VAR(&O) TYPE(*CHAR) LEN(10)

DCL VAR(&P) TYPE(*CHAR) LEN(4)

DCL VAR(&R) TYPE(*CHAR) LEN(4)

DCL VAR(&S) TYPE(*CHAR) LEN(10)

DCL VAR(&T) TYPE(*CHAR) LEN(10)

DCL VAR(&U) TYPE(*CHAR) LEN(10)

DCL VAR(&V) TYPE(*CHAR) LEN(10)

DCL VAR(&W) TYPE(*CHAR) LEN(10)

DCL VAR(&X) TYPE(*CHAR) LEN(50)

DCL VAR(&SCREEN) TYPE(*CHAR) LEN(10)

DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(256)

DCL VAR(&MSGF) TYPE(*CHAR) LEN(10)

DCL VAR(&MSGFLIB) TYPE(*CHAR) LEN(10)

DCL VAR(&MSGID) TYPE(*CHAR) LEN(7)

MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(FWDMSG))

IF (&B *EQ 'M') THEN(GOTO MEMBER)

IF (&B *EQ 'O') THEN(GOTO OBJECT)

GOTO LIBRARY

MEMBER:

CHGVAR VAR(&SCREEN) VALUE('WRKMBRPDM')

GOTO CMDLBL(WRONGSCRN)

RETURN

OBJECT:

CHGVAR VAR(&SCREEN) VALUE('WRKOBJPDM')

GOTO CMDLBL(WRONGSCRN)

RETURN

LIBRARY:

CHGVAR VAR(&SCREEN) VALUE('WRKLIBPDM')

GOTO CMDLBL(WRONGSCRN)

RETURN

WRONGSCRN:

SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('Option' +

*BCAT &C *BCAT 'is not valid from the' +

*BCAT &SCREEN *BCAT 'display') +

MSGTYPE(*ESCAPE)

FWDMSG:

RCVMSG MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) +

SNDMSGFLIB(&MSGFLIB)

SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +

MSGDTA(&MSGDTA)

RETURN

ENDPGM

Figure 2: A skeletal CL program for defining PDM options

MEMBER:

CLRPFM FILE(&L/&F) MBR(&N)

GOTO FWDMSG

Figure 3: Executing the Z1 option from WRKMBRPDM clears the selected member

OBJECT:

IF COND(&T *NE '*FILE') THEN(DO)

SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('Object' +

*BCAT &L *TCAT '/' *CAT &N *BCAT 'type' +

*BCAT &T *BCAT 'is not a file') +

MSGTYPE(*ESCAPE)

ENDDO

RTVOBJD OBJ(&L/&N) OBJTYPE(&T) OBJATR(&OBJATR)

IF COND(%SST(&OBJATR 1 2) *NE 'PF') THEN(DO)

SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('File' +

*BCAT &N *BCAT 'is not a physical file') +

MSGTYPE(*ESCAPE)

RETURN

ENDDO

RTVMBRD FILE(&L/&N) MBR(*FIRSTMBR) RTNMBR(&MBR_1_NAME)

MONMSG MSGID(CPF3019) EXEC(DO)

RCVMSG

SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('File' +

*BCAT &N *BCAT 'has no members')

RETURN

ENDDO

RTVMBRD FILE(&L/&N) MBR(&MBR_1_NAME *NEXT)

MONMSG MSGID(CPF3049) EXEC(DO)

RCVMSG

CLRPFM FILE(&L/&N)

GOTO FWDMSG

ENDDO

?CLRPFM ?*FILE(&L/&N) ??MBR(*FIRST)

MONMSG MSGID(CPF6801) EXEC(RETURN)

GOTO FWDMSG

Figure 4: Executing option Z1 from WRKOBJPDM runs this routine

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$0.00 Raised:
$