Starter Kit- Chapter 29 System iNetwork (formerly iSeries Network)
Home Site Map Contact Us My Profile Log In Join Now!
Info Centers
 Forums

 Tech Center

 News & Analysis

 Solution Center

 UK Centre
Popular Spots
 25th Anniversary

 Article Archive

 ProVIP Center (Club Tech)

 Code

 System i DocFinder

 Essential Guides

 Blogs

 Wikis

 e-Learning

 Webcasts

 Podcasts

 System i Jobs

 Events
Products
 i5 Route Finders

 Learning Center (Store)

 Product Directory
Network Poll
Determining a programmer's desktop requirements is not a black-and-white proposition, but matching equipment to programmer type can help productivity. Which "programmer type" are you?
Vote Now!
Network Memberships
 See Membership Levels

 Free E-Mail Newsletters

 Free RSS Feeds

 Subscribe/Join

 Upgrade Now

 Renew Now
About Us
 About the Network

 Network Publications

 Tech Editor Profiles

 Editorial Calendar

 Contact Us

 Subscribe

 Media Kit (PDF)

 Write For Us


System iNetwork November Sponsor





        System iNetwork November Sponsor


Home » Starter Kit » TOC » Chapter 29
  AS/400-iSeries Starter Kit


Chapter 29 - Teaching Programs to Talk

Speak, program! Speak!" That's one way to try to get your program to talk (perhaps success is more likely if you reward good behavior with a treat). However, to avoid finding you actually barking orders, I want to introduce SNDUSRMSG (Send User Message), an OS/400 command you can use to "train" your programs to communicate. The SNDUSRMSG command exists for the sole purpose of communicating from program to user and includes the built-in ability to let the user talk back.

In Chapter 7, I covered the commands you can use to send impromptu messages from one user to another: SNDMSG (Send Message), SNDBRKMSG (Send Break Message), and SNDNETMSG (Send Network Message). Programs can also use these commands to send an informational message to a user, but because these commands provide no means for the sending program to receive a user response, their use for communication between programs and users is limited. In contrast, the SNDUSRMSG command lets a CL program send a message to a user or a message queue and then receive a reply as a program variable.

Basic Training

Figure 29.1 shows the SNDUSRMSG command screen. The message can be an impromptu message or one you've defined in a message file. To send an impromptu message, just type a message of up to 512 characters in the MSG parameter. To use a predefined message, enter a message ID in the MSGID parameter. The message you identify must exist in the message file named in the MSGF parameter.

The MSGDTA parameter lets you specify values to take the place of substitution variables in a predefined message. For example, message CPF2105

   (Object &1 in &2 type *&3 not found) 

has three data substitution variables: &1, &2, and &3. When you use the SNDUSRMSG command to send this message, you can also send a MSGDTA string that contains the substitution values for these variables. If you supply these values in the MSGDTA string:

'CSTMAST   ARLIB     FILE   '

the message appears as

Object CSTMAST in ARLIB type *FILE not found

If you do not supply any MSGDTA values, the original message is sent without values (e.g., Object in type * not found).

The character string specified in the MSGDTA parameter is valid only for messages that have data substitution variables. It is important that the character string you supply is the correct length and that each substitution variable is positioned properly within that string. The previous example assumes that the message is expecting three variables (&1, &2, and &3) and that the expected length of each variable is 10, 10, and 7, respectively, making the entire MSGDTA string 27 characters long. How do I know that? Because each system-defined message has a message description that includes detailed information about substitution variables, and I used the DSPMSGD (Display Message Description) command to get this information.

Every AS/400 is shipped with QCPFMSG (a message file for OS/400 messages) and several other message files that support particular products. You can also create your own message files and message IDs that your applications can use to communicate with users or other programs. For more information about creating and using messages, see the AS/400 Control Language Reference (SC41-0030) and the AS/400 Control Language Programmer's Guide (SC41-8077).

The next parameter on the SNDUSRMSG command is VALUES, which lets you specify the value or values that will be accepted as the response to your message, if one is requested. When you specify MSGTYPE(*INQ) and a CL variable in the MSGRPY parameter (discussed later), the system automatically supplies a prompt for a response when it displays the message. The system then verifies the response against the valid values listed in the VALUES parameter. If the user enters an invalid value, the system displays a message saying that the reply was not valid and resends the inquiry message. To make sure the user knows what values are valid, you should list the valid values as part of your inquiry message.

In the DFT parameter, you can supply a default reply to be used for an inquiry message when the message queue that receives the message is in the *DFT delivery mode or when an unanswered message is deleted from the message queue. The default value in the SNDUSRMSG command overrides defaults specified in the message description of predefined messages. The system uses the default value when the message is sent to a message queue that is in the *DFT delivery mode, when the message is inadvertently removed from a message queue without a reply, or when a system reply list entry is used that specifies the *DFT reply.

Oddly enough, this value need not match any of the supplied values in the VALUES parameter. This oddity presents some subtle problems for programmers. If the system supplies a default value not listed in the VALUES parameter, it is accepted. However, if a user types the default value as a reply, and the default is not listed in the VALUES parameter, the system will notify the user that the reply was invalid. To avoid such a mess, I strongly recommend that you use only valid values (those listed in the VALUES parameter) when you supply a default value.

The MSGTYPE parameter lets you specify whether the message you are sending is an *INFO (informational, the default) or *INQ (inquiry) message. Both kinds appear on the destination message queue as text, but an inquiry message also supplies a response line and waits for a reply.

The TOMSGQ parameter names the message queue that will receive the message. You can enter the name of any message queue on the local system, or you can use one of the following special values:

  • * -- instructs the system to send the message to the external message queue (*EXT) if the job is interactive or to message queue QSYS/QSYSOPR if the program is being executed in batch.
  • *SYSOPR -- tells the system to send the message to the system operator message queue, QSYS/QSYSOPR.
  • *EXT -- instructs the system to send the message to the job's external message queue. Inquiry messages to batch jobs will automatically be answered with the default value, or with a null value (*N) if no default is specified. Keep in mind that although messages can be up to 512 characters long for first-level text, only the first 76 characters will be displayed when messages are sent to *EXT.

The TOUSR parameter is similar to TOMSGQ but lets you specify the recipient by user profile instead of by message queue. You can enter the recipient's user profile, specify *SYSOPR to send the message to the system operator at message queue QSYS/QSYSOPR, or enter *REQUESTER to send the message to the current user profile for an interactive job or to the system operator message queue for a batch job.

One problem emerges when using the SNDUSRMSG command to communicate with a user from the batch job environment. In the interactive environment, both the TOUSR and TOMSGQ parameters supply values that let you communicate easily with the external user of the job. In the batch environment, the only values provided for TOUSR and TOMSGQ direct messages to the system operator as the external user. There are no parameters to communicate with the user who submitted the job.

The CL code in Figure 29.2 solves this problem. When you submit a job, the MSGQ parameter on the SBMJOB (Submit Job) command tells the system where to send a job completion message. You can retrieve this value using the RTVJOBA (Retrieve Job Attributes) command and the SBMMSGQ and SBMMSGQLIB return variables. The program in Figure 29.2 uses the RTVJOBA command to retrieve the name of the message queue and tests variable &type to determine whether the current job is a batch job (&type=&@batch). If so, SNDUSRMSG can send the message to the message queue defined by the &sbmmsgq and &sbmmsgqlib variables. If the job is interactive, the SNDUSRMSG command can simply direct the message to the external user by specifying TOUSR(*REQUESTER).

You can use the MSGRPY parameter to specify a CL character variable (up to 132 characters long) to receive the reply to an inquiry message. Make sure that the length of the variable is at least as long as the expected length of the reply; if the reply is too short, it will be padded with blanks to the right, but if the reply exceeds the length of the variable, it will be truncated. The first result causes no problem, whereas a truncated reply may cause an unexpected glitch in your program.

An inquiry message reply must be a character (alphanumeric) reply. If your application requires the retrieval of a numeric value, it is best to use DDS and a CL or high-level language (HLL) program to prompt the user for a reply. This approach ensures that validity checking is performed for numeric values.

Alas, the SNDUSRMSG command also exhibits another oddity: If you don't specify a MSGRPY variable but do specify MSGTYPE(*INQ), the command causes the job to wait for a reply from the message queue but doesn't retrieve the reply into your program.

The last parameter on the SNDUSRMSG command is TRNTBL, which lets you specify a translation table to process the response automatically. The default translation table is QSYSTRNTBL, which translates lowercase characters (X'81' through X'A9') to uppercase characters. Therefore, you can check only for uppercase replies (e.g., Y or N) rather than having to code painstakingly for all lowercase and uppercase possibilities (e.g., Y, y, N, n).

Putting the Command to Work

Figure 29.3 shows how the SNDUSRMSG command might be implemented in a CL program. Notice that SNDUSRMSG is first used for an inquiry message. The message is sent to *REQUESTER to make sure the entire message text is displayed on the queue. The job determines whether or not the daily report has already been run for that day and, if it has, prompts the user to verify that the report should indeed be run again.

The program explicitly checks for a reply of Y or N and takes appropriate action. Some people might argue that this is overcoding, because if you specified VALUES('Y' 'N') and you check for Y first, you can assume that N is the only other possibility. Although you can make assumptions, it is best if all the logical tests are explicit and obvious to the person who maintains the program.

Also notice that the SNDUSRMSG command is used again in Figure 29.3 to send informational messages that let the user know which action the program has completed (the completion of the task or the cancellation of the request to process the daily report, depending on the user reply). You will find that supplying informational program-to-user messages will endear you to your users and help you avoid headaches (e.g., multiple submissions of the same job because the user wasn't sure the first job submission worked).

Knowing When To Speak

As shown in the CL program example, using SNDUSRMSG to prompt the user for a simple reply makes good use of the command's capabilities. This function is somewhat different from prompting for data when you submit a job. I don't recommend using the SNDUSRMSG command to retrieve data for program execution (e.g., branch number, order number range, date range), because SNDUSRMSG offers minimal validity checking and is not as user-friendly as a DDS-coded display file prompt can be. Instead, you should create prompts for data as display files (using DDS) and process them with either a CL or HLL program.

In a nutshell, the SNDUSRMSG command is best suited to sending an informational message to the user to relate useful information (e.g., "Your job has been submitted. You will receive a message when your job is complete.") or to sending an inquiry message that lets the user choose further program action. The SNDUSRMSG command can teach your programs to talk, but the vocabulary associated with this command is specific to these two tasks.

Now that you know how to train your program to talk to users, you can save the biscuits for the family pooch. The next challenge: teaching your programs to communicate with each other! You'll be able to master that after I explain how to use the SNDPGMMSG (Send Program Message) command, which lets you send messages from program to program with information such as detected program errors and requirements for continued processing. Who says you can't teach an old dog new tricks?


Starter Kit for the AS/400, 2nd Edition
Copyright 1994 by Duke Press
DUKE COMMUNICATIONS INTERNATIONAL
Loveland, Colorado

All rights reserved. No part of this book may be reproduced in any form by any electronic or mechanical means (including photocopying, recording, or information storage and retrieval) without permission in writing from the publisher.

It is the reader's responsibility to ensure procedures and techniques used from this book are accurate and appropriate for the user's installation. No warranty is implied or expressed.

This book was printed and bound in the United States of America.
Second Edition: April 1994

ISBN 10882419-09-X



  Sponsored Links   Featured Links


Penton Technology Media
Connected Home | SQL Server Magazine | Windows IT Pro
Report Bugs | Contact Us | Comments/Suggestions | Terms & Conditions | Privacy Policy | Trademarks
See Membership Levels | Subscribe | Free E-mail Newsletters | Free RSS Feeds | My Profile | Upgrade Now | Renew Now

Copyright © 2008 - Penton Technology Media
Penton Media
System i is a trademark of International Business Machines Corporation and is used by Penton Media, Inc., under license. SystemiNetwork.com is published independently of International Business Machines Corporation, which is not responsible in any way for the content. Penton Media, Inc., is solely responsible for the editorial content and control of the System iNetwork.