Guild Companies, Inc.  
 
Midrange Guru - Tech Tips
OS/400 Edition
Volume 2, Number 24 - March 29, 2002

Odds and Ends

Dear Readers:

Response to the first Odds and Ends column was overwhelmingly positive, so I am going to continue this feature. In each Odds and Ends edition, I will feature answers to questions that, in my opinion, aren't worth featuring as Midrange Guru tips by themselves.

-- Ted

Question:

How can I make my iSeries run an FTP session in batch mode?

Answer:

Put the FTP commands in a source physical file member. For example, you might call the member FTPIN and put it in file MYLIB/MYFILE. Create another member for FTP output.

Use the Override with Database File (OVRDBF) command to override INPUT and OUTPUT to these members.

For example:

OVRDBF INPUT TOFILE(MYLIB/MYFILE) MBR(FTPIN)
OVRDBF OUTPUT TOFILE(MYLIB/MYFILE) MBR(FTPOUT)
FTP HostNameOrIP#
DLTOVR (INPUT OUTPUT)

Question:

Since I started programming, which was over 20 years ago, I have heard from time to time that I/O operations generate a lot of machine code.  I was under the impression that the following code was not as good as another example:

Fpaywork   uf   e             disk
C                   read      PayRec
C                   dow       not %eof(PayWork)
C                   update    PayRec
C                   read      PayRec
C                   enddo
C*
C                   eval      *inLR = *on

This is the other example I was referring to:

Fpaywork   uf   e             disk
C                   exsr      Read
C                   dow       not %eof(PayWork)
C                   update    PayRec
C                   exsr      Read
C                   enddo
C*
C                   eval      *inLR = *on
C*
C     Read          begsr
C                   read      PayRec
C                   endsr

I was told that the reason for this is due to the fact that the machine code for the read is only generated once in the first example but it is generated twice in the second example.

What's the truth? Does it really matter if I code an I/O twice, as in the first example, or just once, as in the second?

Answer:

I had to ask the RPG compiler development team in Toronto to get an answer to this one. Here is what Barbara Morris had to say:

The RPG compilers already generate their own internal subroutines for the I/O.  Also, for RPG IVat least, part of the I/O is done in the RPG runtime. The setup for calling the internal subroutine will be greater than the setup for an EXSR, but most of the duplication has already been taken care of for you.

The experiments I've done indicate that each read adds about 1,500 bytes and each EXSR adds about 150 bytes. That's probably not enough difference to warrant putting the read in the subroutine just for the sake of reducing the size of the program, especially just for the case of two, as in your loop.

I guess I'd say having two READs is better than having EXSRs, just because it's easier to see what's going on. Although, if there was a strict standard for subroutine naming, and that subroutine was named read_payrec, the EXSRs wouldn't be too bad.

Question:

MHCPDT is an alphanumeric field read from a file. We want to reference it and parts of it as numerics, so we created the following data structure:

I            DS                                       
I                                        1   6 MHCPDT 
I                                        1   60DSCPDT 
I                                        1   20MHCPYR 
I                                        3   60MHCPKY 
I                                        3   40MHCPMO 
I                                        5   60MHCPDA 

When we reference DSCPDT in an IFEQ statement, it gives a decimal data error.  When we remove MHCPDT from the data structure and add a MOVE calculation to copy MHCPDT to DSCPDT, it works fine. We're confused. Could you shed some light on this?

Answer:

MHCPDT probably has some blanks. When you use the MOVE opcode to copy an alpha value to a numeric one, RPG converts the data to numeric if necessary. For example, a blank gets converted to a zero. That's why the MOVE works. However, when the system copies a value into a data structure no conversion is done to other subfields that occupy the same positions.

Question:

How can I make SDA sort the fields in a record format in a display file by position?

Answer:

From the Work with Display Records panel, use option 12 (Design Image) to select the format. Press F4 to display the fields, then F6 to sort them.

Question:

Can I use SQL to change only the rightmost three positions of a six-character field?

Answer:

Yes. Use the substring function to extract the portions you want to keep intact. Concatenate them to the new value:

update mytable
   set class = substring(class,1,3) concat 'XYZ'

The first three characters of class remain the same. The last three are changed to XYZ.

Question:

We typically produce RPG IV programs that use subfile error handling. We have run into a case where we just wanted to use a CL program that uses a regular screen format, a message subfile format, and a message subfile control format. Do you know if or how we can do that?

Answer:

Here's an example that will do exactly what you want. Compile JKL001D as a display file and JKL001C as a CLP or CLLE:

     A* member JKL001D
     A                                      DSPSIZ(24 80 *DS3)
     A          R FORMAT01
     A                                      CA03(03)
     A                                      OVERLAY
     A                                  1 31'Generate Some Report'
     A                                  1 72DATE
     A                                      EDTCDE(Y)
     A                                  2 72TIME
     A                                  5  8'Enter range of dates in MMDDYY for-
     A                                      mat. You may leave ending date'
     A                                  6  8'blank if the report is to be run f-
     A                                      or only one day.'
     A                                  8  8'Beginning date ...................-
     A                                      ...........:'
     A            SBGNDATE       6Y 0B  8 55EDTCDE(4)
     A                                  9  8'Ending date ......................-
     A                                      ...........:'
     A            SENDDATE       6Y 0B  9 55EDTCDE(4)
     A                                 22  6'F3=Cancel request'
     A                                 22 27'Enter=Generate report'
     A
     A          R MSGSFL                    SFL
     A                                      SFLMSGRCD(24)
     A            MSGKEY                    SFLMSGKEY
     A            PGMNAM                    SFLPGMQ
     A
     A          R MSGCTL                    SFLCTL(MSGSFL)
     A                                      SFLSIZ(0010)
     A                                      SFLPAG(0001)
     A                                      OVERLAY
     A                                      SFLDSP
     A                                      SFLDSPCTL
     A                                      SFLINZ
     A N87                                  SFLEND
     A            PGMNAM                    SFLPGMQ(10)


/* member JKL001C */
             PGM

             DCLF       FILE(JKL001D)
             DCL        VAR(&NBGNDATE) TYPE(*CHAR) LEN(6)
             DCL        VAR(&NENDDATE) TYPE(*CHAR) LEN(6)
             DCL        VAR(&WBGNDATE) TYPE(*CHAR) LEN(8)
             DCL        VAR(&WENDDATE) TYPE(*CHAR) LEN(8)
             DCL        VAR(&DATEWDW8) TYPE(*CHAR) LEN(8)
             DCL        VAR(&DATEWDW6) TYPE(*CHAR) LEN(8)
             DCL        VAR(&MSGTXT) TYPE(*CHAR) LEN(78)
             /* Variables needed to determine program name */
             DCL        VAR(&MSGKEY) TYPE(*CHAR) LEN(4)
             DCL        VAR(&SENDER) TYPE(*CHAR) LEN(80)

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

Prelims:
             /* Determine the name of the program */
             SNDPGMMSG  MSG('Dummy message') TOPGMQ(*SAME) +
                          MSGTYPE(*INFO) KEYVAR(&MSGKEY)
             RCVMSG     PGMQ(*SAME) MSGTYPE(*INFO) MSGKEY(&MSGKEY) +
                          RMV(*YES) SENDER(&SENDER)
             CHGVAR     VAR(&PGMNAM) VALUE(%SST(&SENDER 27 10))

             /* Get earliest acceptable date */
             CHGVAR     VAR(&DATEWDW8) VALUE('20020101') /* yymd */
             CVTDAT     DATE(&DATEWDW8) TOVAR(&DATEWDW6) +
                          FROMFMT(*YYMD) TOFMT(*JOB) TOSEP(*JOB) /* +
                          job date format */

             /* Create the msgf for demo purposes.  Normally this msgf */
             /* would already exist in a production library */
             CRTMSGF    MSGF(QTEMP/JKLMSG)
             MONMSG     MSGID(CPF2112) EXEC(GOTO BEGIN)
             ADDMSGD    MSGID(JKL1001) MSGF(QTEMP/JKLMSG) +
                          MSG('Ending date must not be before +
                          beginning date')
             ADDMSGD    MSGID(JKL1002) MSGF(QTEMP/JKLMSG) MSG('Dates +
                          must not be before &1.') FMT((*CHAR 8))
Begin:
             RMVMSG     CLEAR(*ALL)

             /* loop until F3 pressed or data is valid */
GetInput:
             SNDF       RCDFMT(MSGCTL)
             SNDRCVF    RCDFMT(FORMAT01)
             IF         COND(&IN03) THEN(GOTO EndPgm)
             RMVMSG     CLEAR(*ALL)
             CHGVAR &NBGNDATE &SBGNDATE
             CVTDAT     DATE(&NBGNDATE) TOVAR(&WBGNDATE) +
                          FROMFMT(*JOB) TOFMT(*YYMD) TOSEP(*NONE)
             CHGVAR &NENDDATE &SENDDATE
             CVTDAT     DATE(&NENDDATE) TOVAR(&WENDDATE) +
                          FROMFMT(*JOB) TOFMT(*YYMD) TOSEP(*NONE)
             IF         COND(&WENDDATE *LT &WBGNDATE) THEN(DO)
             SNDPGMMSG  MSGID(JKL1001) MSGF(QTEMP/JKLMSG) TOPGMQ(*SAME)
             GOTO       CMDLBL(GETINPUT)
             ENDDO
             IF         COND((&WBGNDATE *LT &DATEWDW8) *OR +
                             (&WENDDATE *LT &DATEWDW8)) THEN(DO)
             SNDPGMMSG  MSGID(JKL1002) MSGF(QTEMP/JKLMSG) +
                          MSGDTA(&DATEWDW6) TOPGMQ(*SAME)
             GOTO       CMDLBL(GETINPUT)
             ENDDO
EndInput:
             /* Insert commands to process input here */
             RETURN
Error:
             RCVMSG     MSGQ(*PGMQ) MSGTYPE(*EXCP) MSG(&MSGTXT)
             MONMSG     MSGID(CPF0000)
             SNDPGMMSG  MSG(&MSGTXT) TOPGMQ(*SAME)
             MONMSG     MSGID(CPF0000)
             GOTO       CMDLBL(GETINPUT)

EndPgm:
             ENDPGM

This short program allows a user to enter two dates that will be used in building a report of some sort. It checks for several errors--invalid dates, second date before first date, and date not in current year. When it finds an error, it sends it to the error subfile.

Sponsored By
TRAMENCO

Learn what's over the horizon for the iSeries and AS/400, and how it will impact your career, by attending the premier training event of 2002. It's the iSeries and AS/400 Connection Conference June 16 – 19, 2002 in Naples Florida. Join 19 of the industries greatest minds including Dr. Frank Soltis, Skip Marchesani, Wayne O. Evans, Susan Gantner, Jon Paris, Marie Finnegan-Cronin, and Howard Arner, Jr. as they deliver AS/400 training and education to prepare you for the challenges of tomorrow. A full agenda of 96 sessions (including 10 hands-on labs) provide practical instruction in a full range of topics, including:

  • Understanding Websphere Development Studio

  • Accessing DB2/400 data from Linux

  • Learning how JavaBeans are used

  • Make the most of RPG IV's built in functions

  • SQL Tricks and Techniques

  • ABCs of System Management

  • And much more!
Whether you are an old pro, or just getting your feet wet, there is something for everyone during this intensive four-day conference. Best of all, your classroom is the Registry Resort and Spa, Naples Florida's premier 5-star resort. To register, or for more information, call 1 800 897.5923, or go to the web at www.tramenco.com. But hurry, you must register before May 15, 2002 to save $200 off the standard registration and be eligible for special hotel rates.

THIS ISSUE
SPONSORED BY:
Profound Logic Software
TRAMENCO
BACK ISSUES
TABLE OF CONTENTS
More Qshell Output in ASCII
Odds and Ends
Reader Feedback and Insights: Remote Software
  Newsletters | Subscribe | Advertise | About Us | Contact | Search | Home  
  Last Updated: 3/29/02
Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved.