37
Technical Quiz 1. Explain the difference between DOW and DOU Ans: In Case of Dow the condition is checked first and then the loop is executed, in case of Dou the loop is executed at atleast once and then the condition is checked . There is a possibility that the loop is not executed even once but in case of Dou the loop is definetly executed at least once. 2. What is a library list and how can it be changed? Ans: Library list is a list of libraries that is given to each job when it is started , we can change the library list using some CL commands EDTLIBL , CHGLIBL , CHGCURLIB,CHGSYSLIBL,CHGUSRLIBL. 3. What is QSYS library and what is it used for ? Ans: QSYS is the system library that contains some of the system defined objects and will also contain Authorization list . 4. In a display file, what do display attributes RI, PR,PC and HI mean? Ans: RI – Reverse Image PR – Protected PC – Position Cursor HI – High Intensity 5. what is the difference between CHAIN and STELL? Ans: Setll sets the pointer to the lower limit of the key field specified in factor 1 and does not read the record. Chain – Will Set the pointer on the specified key field in factor 1 and reads the record 6. What is QTEMP and how is it created? Ans : QTEMP is a systems library specified in the user part of the library list that will contain user data and is created automatically the moment an interactive job starts 7. How many files can you declare in a CL program? Ans: One 8. What do you use to MONMSG command in CL programs for ? Ans: TO trap run time error messages in a CL program 9. What are data queues? Ans: Data Queues are objects that are used for program to program communication. 10.What are DDM files? Ans: Data Distributed Management files 11.If an RPG program frequently reads the same small set of records from a file, how can the efficiency of the program be improved? Ans: You can load the records into a run time array and then process the run time array from within the program 12. what is the difference between RETRN with LR indicator set on and RETRN with LR set off? Ans: Return will just return the control to the calling program. Without closing or initializing the local variables or will not clear the memory. Where as LR will close all file and initialize all local variables and clear the memory used by that program Setting on LR (Last Record) will close files and free resources occupy by the program. Initialization will occur on the next call to the program. Not setting on LR (in OPM programs) will keep the program in 1

Printed RPG Quiz Technical

Embed Size (px)

Citation preview

Page 1: Printed RPG Quiz Technical

Technical Quiz

1. Explain the difference between DOW and DOUAns: In Case of Dow the condition is checked first and then the loop is executed, in case of Dou the loop is executed at atleast once and then the condition is checked . There is a possibility that the loop is not executed even once but in case of Dou the loop is definetly executed at least once.

2. What is a library list and how can it be changed?Ans: Library list is a list of libraries that is given to each job when it is started , we can change the library list using some CL commands EDTLIBL , CHGLIBL , CHGCURLIB,CHGSYSLIBL,CHGUSRLIBL.

3. What is QSYS library and what is it used for ?Ans: QSYS is the system library that contains some of the system defined objects and will also contain Authorization list .

4. In a display file, what do display attributes RI, PR,PC and HI mean?Ans: RI – Reverse Image PR – Protected PC – Position Cursor HI – High Intensity5. what is the difference between CHAIN and STELL?Ans: Setll sets the pointer to the lower limit of the key field specified in factor 1 and does not read the record.Chain – Will Set the pointer on the specified key field in factor 1 and reads the record

6. What is QTEMP and how is it created?Ans : QTEMP is a systems library specified in the user part of the library list that will contain user data and is created automatically the moment an interactive job starts

7. How many files can you declare in a CL program?Ans: One

8. What do you use to MONMSG command in CL programs for ?Ans: TO trap run time error messages in a CL program

9. What are data queues?Ans: Data Queues are objects that are used for program to program communication.10.What are DDM files?Ans: Data Distributed Management files11.If an RPG program frequently reads the same small set of records from a file, how can the efficiency of the program be improved?Ans: You can load the records into a run time array and then process the run time array from within the program12. what is the difference between RETRN with LR indicator set on and RETRN with LR set off?Ans: Return will just return the control to the calling program. Without closing or initializing the local variables or will not clear the memory. Where as LR will close all file and initialize all local variables and clear the memory used by that programSetting on LR (Last Record) will close files and free resources occupy by the program. Initialization will occur on the next call to the program. Not setting on LR (in OPM programs) will keep the program in memory, keeps file open and pointers set, retains variable values, and prevents the *INZSR from being executed the next time the program is called, as well as INZ specified in your D-specs. As a rule, I never seton LR when a program will be called multiple times. This rule most definitely applied to a trigger program that could be called hundreds or possibly thousands of times. 13. How would you debug a job in batch?

Ans: Service Job14. How would you submit a job to batch from an RPG program?

Ans: QCMDEXC

1

Page 2: Printed RPG Quiz Technical

15. What are the *PSSR and *INZSR subroutines?Ans: *PSSR is a program status subroutine that is executed automatically if there an error in the program or a file and if for this file specification there a *PSSR defined in the file specification *INZSR is an initialize subroutine that is executed automatically whenever this program is called .

16. What is the difference between CLEAR and RESET?Ans: Clear will clear the variables and Reset will reset the variables to the initial value.

17.How and when is commitment control used?Ans: Commitment control is used to commit the changes made to the records of a file from the last rollback or commit. For commitment control jourmalling is mandatory and the file in the program should be opened under commitment control

17. A program writes to a data queue. If you wish to see the content of the data queue, what command would you use? Ans: QRCVDTAQ18. What is a shared ODP and how and when would you use it?Ans: For a file if you want to share the open data path in different programs within a job then you will override the database file in a shared mode that is SHARE(*YES).19.What APIs have you used? Ans: QCMDEXC,QRCVDTAQ,QSNDDTAQ.20.What is ILE and how does it differ from OPM?Ans: ILE – Integrated Language Env. - In OPM the binding is done at the run time. In ILE the binding is done at compilation time.22.In an ILE environment, what is the difference between RCLRSC and RCLACTGRP?Ans: If a user-named activation group is left in the job, you can delete it by using the Reclaim Activation Group (RCLACTGRP) command. This command allows you to delete named activation groups after your application has returned. Only activation groups that are not in use can be deleted with this command. While The RCLRSC command may be used to close the files based on a particular call-level number passed to that command.

23.In ILE, what is the maximum number of array elements in an array?Ans : ????

24.What is the Built In Function %EQUAL used for?Ans: With a SETLL statement if you give an indicator under equal column then that indicator is set on if an equal match is found in the file , instead of using an indicator in RPG IV after setll we can check for an equal match using %Equal BIF

25.Which ILE operation code is the equivalent of the MOVE operation code? Ans: Eval26.What is the difference between subroutine and procedure?

Ans: Procedures can be called across different modules but a subroutine can only be called within a module or program

27.What is special about STRCMTCTL and OVRDBF in an ILE environment?Ans: STRCMTCTL and OVRDBF can be specified for all the programs within an activation group

28.Which character is used to define an indicator type variable?Ans : ‘N’

29.Which type of program is bound by reference? Ans: Service Programs

30.I am having an assignment in which it is asked to display specific page of subfile. e.g. I am currently on 10th page of subfile, now if I wants to display 2nd page directly..... How should I do?Right now I have taken a Input/Output field in control record format, to specify the page to be displayd. How should I use this value to display specific page on LOAD ALL subfile.Is SFLRCDNBR or SFLCSRRRN usuful in this case? Or any other keyword.Please, it is urgent. If possible try to elaborate your concept with an example...Ans :If your SFLPAG = 10, 2nd page should start on 11th record. Move this number to SFLRCDNBR and EXFMT again.

2

Page 3: Printed RPG Quiz Technical

31.how do you access all members in pf? : WRKMBRPDM 32. How do use the new File Built-in Functions?Ans : OS/400 Version 4, Release 2 RPG IV supports the elimination of the Resulting Indicators. In their place, several new built-in functions have been introduced. Most of these new built-in function provide information about the result of File operations similar to the Result indicators. But instead of coding Resulting indicator 3, for example, to check for the end-of-file condition, you simply check the value of the %EOF built-in function.

The built-in functions that replace the Resulting Indicators include:%FOUND, %EOF, %EQUAL. In addition, there are %OPEN, %STATUS, and %ERROR. Mysteriously missing is %LOCK to check for a record lock condition.

%FOUND : returns an *ON or *OFF condition if the previous File operation returns a record-found condition. This is particularly useful on the CHAIN operation. Realize, however, that when CHAIN sets on Resulting indicator 1, a not-found condition is signaled. Whereas, without coding Resulting Indicator 1, the %FOUND built-in function returns the found condition. %EOF : can be used to check for end-of file, beginning of file, or subfile full conditions. A READ and READE return %EOF=*ON if the end of file is reached. READP and READPE return %EOF=*ON if the beginning of file is reached. The WRITE operation returns %EOF=*ON if the WRITE operation to a subfile detail record returned a subfile-full condition. %EQUAL : is used by the SETLL operation to indicate that it detected a record in the file with a key equal to that of the value specified in Factor 1. Since SETLL does not read the record, does not lock the record, and does not copy the data into the input buffer, SETLL is much faster and less of an impact on the performance of the application than other operations, such as CHAIN. Use CHAIN when you need to retrieve the record, use SETLL and %EQUAL when you need to only check for the existence of a record. %OPEN : is used to check to see if a file has already been opened. The built-in function returns *ON if the file is opened, otherwise it returns *OFF.

33. What is the new E operation extender used for?Ans :The new (E) operation extender is used to cause the %ERROR and %STATUS built-in functions to be initialized after an operation is performed. That is, these built-in functions and the E operation extender are used in place of Resulting Indicator 2 on all operation codes that currently support Resulting Indicator 2 as an error condition.For example, to check to see if a record is locked, you would code the following:.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq C CustNO Chain(E) CustMast C if %ERROR = *ON C Select C When %STATUS = 1221 C exsr UpdateNoRead C When %STATUS = 1218 C exsr RecdLocked C endSL C ELSE C if %FOUND( CustMast ) C exsr whatever... C endif

3

Page 4: Printed RPG Quiz Technical

C endifThe concept is to first check %ERROR for a generalized error condition, and then check %STATUS for the specific error. Note that no resulting indicators are used in the previous example. The normal not-found condition is checked using the %FOUND built-in function rather than testing Resulting Indicator 1.

34. What good are the %TRIM, %TRIML and %TRIMR built-in functions?Ans : The use of the TRIM functions is very limited, in that they support only the use of character variables and data structures. Numeric fields, and zero-fill values are not supported. They do, however, provide some useful function for string handling. For example, in RPG IV, one line of code is all that's needed to left-adjust a value within a field. For example:.....CCRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq C ExFmt CustMaint C Eval CustName=%TrimL(CustName)Typically, the %TRIM function is the only one of the three that get used. The other two, however, do have their place.%TRIM removes trailing and leading blanks from a field, and returns the remaining value, in place, within the expression. The returned value is treated similar to a constant value with leading or trailing blanks.%TRIML removes leading blanks (trim-left) from a field, and returns the value in place, within the expression.%TRIMR removes trailing blanks (trim-right) from a field, and returns the value in place, within the expression.The table below illustrates the mechanics of the TRIM functions.Built-InFunction Original Value Returned Value

%TRIM(compname) ' The IBM Corp. ' 'The IBM Corp.'%TRIML(compname) ' The IBM Corp. ' 'The IBM Corp. '%TRIMR(compname) ' The IBM Corp. ' ' The IBM Corp.'It would be wonderful if the TRIMx functions also supported a second parameter that indicated the character to be trimmed. It could default to blanks, but would accept any value. The internal MI instruction TRIML actually does this already, but TRIML and TRIMR do not directly map to this MI instruction. In addition, it would be even nicer if the second parameter supported multiple characters. That is you would be able to specify %TRIMR(CompName : ' .') and it would strip off blanks and periods from the end of the COMPNAME field. -- Dreamer...

35.Why doesn't the %CHAR built-in function work with numeric values?

Ans :The %CHAR built-in function was introduced. However, the function, as designed, only converted DATE values to character values. This proved to be too restrictive a use for this function. In OS/400 V4R4 IBM will added function to %CHAR allowing it to convert all forms of non-character data to character. In that release %CHAR works with numeric values. D Amount 7P 2 Inz(123.45) C Eval text = 'The amount is: ' + %Char( amount )The TEXT field would contain the following after the EVAL operation is performed:'The amount is: 123.45'Unlike %EDITC, the %CHAR built-in function trims off leading blanks. However, %EDITC provides much more editing power than %CHAR. Use %CHAR for basic number to character conversion.

4

Page 5: Printed RPG Quiz Technical

36. What's the difference between CHAIN and SETLL? Is there a performance advantage?

Ans :

37. How many times can we open file in program? how many records can be stroed when E specify *nomax? Ans : I hope you pass this quiz:1) OVRDBF FILE(XXXX) TOFILE(XXXXX) MBR(*ALL)2) Use USROPN and you can open and close it as often as you want3) With the *nomax option, you can store *nomax records.

38. How many Subfile are available? what are difference between themAns : Subfile: you have to write a program and create a display file to generate

subfile. There are basically TWO types of subfiles: 1) Expanding 2) Single Page.Expanding is further divided into TWO types: 1.1) Load All 1.2) Page by Page.

1) Expanding: When SFLSIZ > SFLPAG, it is called as expanding subfile. i.e. Subfile size increases automatically as we add records. e.g. SFLSIZ=20 and if you add 100 records, system extends subfile size for all 100 records.

1.1) Load All: In this type of subfile difference between SLFSIZ and SFLPAG is large. For example SFLSIZ=1000 and SFLPAG=10. In this type, program adds as many records as possible in the subfile (ideally all records. But remember the maximum size of a subfile is only 9999). Therefore this subfile is usually used for small number of records. Advantage: Navigation through the subfile is fast. Disadvantage: Time required to load the subfile is large.

1.2) Page by page: In this type of subfile we generally keep difference between SFLSIZ and SFLPAG is 1. For example SFLSIZ=11 and SFLPAG=10. (We can keep SFLSIZ large but it should not be EQUAL to SFLPAG) That means program loads 1 page of records initially. And then as we press Page Down key, it loads next page of records and so on (Without deleting previously loaded records). Therefore in this type of subfile we have to write code for Page Down key to load 1 page of records. Again subfile size restriction is there and therefore we use this subfile also for small number of records. Advantage: Navigation through the subfile is slow. Disadvantage: Time required to load the subfile is less.

2)Single Page: In this type of subfile, SFLSIZ = SFLPAG. That is subfile is non-expanding. In this type, every time we press Page Down or Page Up program clears subfile and load next or previous page of records. Therefore we have to write code for both Page Down and Page Up keys. As at any moment this subfile contains only records equal to SFLPAG and therefore this subfile can be used for large number of records. Subfile Links : http://publib.boulder.ibm.com/iseries/v5r2/ic2924/index.htmhttp://publib.boulder.ibm.com/iseries/v5r2/ic2924/index.htmhttp://www.rpgiv.com/rpgivforum/mainhttp://publib.boulder.ibm.com/iseries/v5r2/ic2924/index.htmhttp://www.rpgiv.com/rpgivforum/view?SID=20040512105419479536

39. what is the difference in source file and source memberr? Ans : A Source Physical File contains the source for the various objects created. This file has a specific structure.A Physical File contains

5

Page 6: Printed RPG Quiz Technical

data, and the record format can be different for different physical files.Source file is an object over AS/400 but source member is just a source code of RPG,DSPF,PRTF... and Source file used for containing sources member(s) For Example ,Source file name :QRPGSRC is used for containing source member (source code) of RPG

40. How do debug a remote (i.e. "batch") job from an interactive job?Ans :The ability to debug another job has been a long standing requirement for AS/400, now iSeries programmers. It isn't as difficult as it may seem. Whether you need to debug a batch job, another interactive job, or an HTTP server job (browser/CGI program), the following steps can get you started.

Starting Debug for a Remote Job1. Determine the job name of number for the job you need to debug.

Use WRKACTJOB and note the Job name, number and user profile ID.

If debugging a CGI program, look in the joblog of the job for CPF message HTP2001.

2. Run the Start Service Job (STRSRVJOB) command specifying the job to be debugged

e.g., STRSRVJOB JOB(012345/usrid/jobname) 3. Run Start Debug (STRDBG) on the program to be debugged

e.g., STRDBG PGM(libnam/pgmname) UPDPROD(*YES | *NO) 4. At this point the program in the remote job is under debug control

from your job You can now set break points (if you're debugging an RPG IV

program, the source will have already been displayed). Press F12 from within the debugger to return to CMD entry

after setting your break points. 5. Evoke the program in the remote job. If you you're doing a web

browser session, hit the SUBMIT button. 6. You interactive job will "break" at the debug break points and you

can debug application normally.

Ending Debug for a Remote JobEnding the debug session should be done in the following sequence.

1. From your debugging session, run the End Debug (ENDDBG) command 2. Then run the (End Service Job) ENDSRVJOB command

Your session is no longer controlling the remote job. The remote job continues normally.

Special Considerations when Debugging a Web Browser/CGI ProgramTo debug a CGI program that is evoked from a Web Browser session running from the standard IBM HTTP Web Server, you need to do the following in addition to the above.

Before Starting Debug for a Web Browser/CGI Session/Program End the HTTP Server using the following CL command:

ENDTCPSVR *HTTP WARNING!!! -- You MUST include *HTTP as the parameter for

ENDTCPSVR otherwise all TCP/IP server jobs (including telnet, ftp, smtp, etc.) will be ended. And this is a bad thing. IBM sucks for making *ALL the default for ENDTCPSVR.

Restart the HTTP Server using the following CL command: STRTCPSVR *HTTP HTTPSVR(DEFAULT '-minat 1 -maxat 1') This restarts the HTTP server with once instance of each job

type (one for CGI, one for Java, etc.) Using WRKACTJOB in the QHTTPSVR subsystem location the jobs

running. The job whose joblog contains the CPF message HTP2001 is the one

to be debugged.

6

Page 7: Printed RPG Quiz Technical

After Finishing the Debug Session End the HTTP server using the following CL command:

ENDTCPSVR *HTTP Restart the HTTP server using the following CL command, unless

your shop has another process for starting the HTTP server: STRTCPSVR *HTTP

Your system should be back to normal.

41. Pls somebody tell me how to find that weather there is data in PF in CL without defining file in CL? Also how to Maintain access path without using the opnqryf or Logical file or embedded sqlAns : Without defining... file in CL, Runqry / DSPFD command... can be executed in CL pgm or DSPPFM to check... whether data is present in PF or not. You can use RTVMBRD in CL and find the number of records in the file member

42. While Loading SUBFILE I'm getting session and device error, what is the reson and solution?Ans : If you are getting message... in job log as : Incorrect relative record number or field selection error. Then may be chances... are there that you must not have declared... the keyword 'Sfile' i.e Sfile(subfile rcdfmt name : RRN) while declaring... your display file in F-specs. If so then one can get... session or device error.

43.Is there any function in RPGLE that takes a string as parameter and returns its lengthAns : 1. The length of a field's content is %LEN(%TRIMR(FIELD))2. Length of field - %Len(Field) and Length of contents of string -

%Len(%Trim(Field))

44. In my project i generated a report (Invoice Printing). the Sheet is Pre-printed. i am taking the printout in dot Printer. when i feed the paper into the printer it allings at the top . when printing starts it leaves two lines and starts printing i had given the SKIPB(1) in this record format. any one know how to make the printer to print at the top??? Ans : the problem could be connected to the type of printer (model, type, etc). Many printers have a feed function that move ahead the paper to make easier to keep the fold. An other problem can be the FRONTMGN parameter in the Printer file. But it's strange that you have do this without know it :-) You can do a test: prepare an other prtinter file with a line of characters on the first line, and not use the skip or spaceb statements. In this way the print starts on the first line avalaible. If the printer move for two lines the problem is the printer, if not the problem is the prtf

45.Is there any way to rename only one field in a file in RPG without using any prefix ?Ans : IRECORD_NAME I FIELD RNAME_FLD Don't look at the positions, aren't correct.Anothe way:

D myds E DS ExtName(myFile)D MyName E ExtFld(FileFieldName)

or

D DS D FileFieldName D MyName Like(FileFieldName) Overlay(FileFieldName)

7

Page 8: Printed RPG Quiz Technical

46. I need some info. about setting up AS400. What hardware I will need ? Where can I get info. ? Ans : IBM has several books that you can download.Start here;http://publib.boulder.ibm.com/infocenter/iseries/v5r3/ic2924/index.htm

47. I want to type in a letter in word processor and attach data from AS/400 at the end of this letter and send to my users. Is there a way to open a word document in RPG or CL .I can tranfer this document back to AS/400 using ftp, but opening it is a big problem for me. Ans : What about the command STRPCCMD ? With this command you can open a Word document.

48. Execute CL ans RPG programs from a excell macro Is this possible? How?Ans : you can use a VBA macro using an ADODB connection for this issue. The following macro holds an OUTQ.

For example: Private Sub HoldButton_Click() Dim xy As Object Set xy = CreateObject("ADODB.Connection") xy.Provider = "IBMDA400" xy.Properties("data source") = "yourISERIESsystemname" xy.Open xy.Execute "{{hldoutq outq(qprint)}}", , adCmdText If Not xy Is Nothing Then xy.Close Set xy = Nothing MsgBox ("OUTQ QPRINT set to hold")End Sub

Retrieve Database SourceThe Retrieve Database Source (RTVDBSRC) command retrieves the information from an existing physical or logical file and writes to a DDS member.The typical command is RTVDBSRC FILE(MYLIB/MYFILE) TOSRC(MYLIB/QDDSSRC)This will extract the information from the named file and creates a new member (or updates an existing member) into the specified source file.Comments originally entered in the source member will be lost. The field reference (and reference file) is not be retrieved by this tool. Multi-format files are retrieved as "closed as" possible but not a guarantee that all information are retrieved. The tool does not support Field concatenation. Reasons to use this toolFiles were created using Sequel and no source member existed.You lost your DDS source.InstallationMember Type Source FileCRTRTVDB CLP QCLSRCRTVDBSRC CMD QCMDSRCRTVDB1 CLLE QCLLESRCRTVDB2 RPGLE QRPGLESRC

Copy the individual member to the designated source file in your library. Take note that RPGLESRC has a length of 112 and the rest of the source uses the default 92 length.

Create the CRTRTVDB program:CRTCLPGM PGM(Objlib/CRTRTVDB) SRCFILE(Srclib/QCLSRC)Add the Objlib in your library list.Call the CRTRTVDB program to create the utility.CALL CRTRTVDB PARM('Objlib' 'Srclib')RTVDBSRC/*------------------------------------------------------------------*/ /* Programmers Group & Management Resource Copyright 1998 */ /* */

8

Page 9: Printed RPG Quiz Technical

/* \\\\\\\ */ /* ( o o ) */ /*------------------------oOO----(_)----OOo-------------------------*/ /* */ /*System name . . . : Technical Support */ /* Command name . . . : RTVDBSRC */ /* Text . . . . . . . : Retrieve Database Source */ /* */ /* Author . . . . . . : Alex Nubla */ /* Description. . . . : Retrieves the source for an existing */ /* file into a source member. */ /* /* Command parameters: */ /* */ /* ALLOW((*ALL) */ /* */ /* CPP: RTVDB1 */ /* */ /*------------------------------------------------------------------*/ cmd ('Retrieve Database Source') /* -------------------------------------------- */ /* File */ /* -------------------------------------------- */ parm file qfile + min(1) + prompt('File') qfile: + qual *name 10 + expr(*yes) qual *name 10 + dft(*libl) + spcval(*libl *curlib) + expr(*yes) + prompt('Library') /* -------------------------------------------- */ /* To source file */ /* -------------------------------------------- */ parm tosrc qsrcfile + min(1) + prompt('To source file') qsrcfile: + qual *name 10 + expr(*yes) qual *name 10 + dft(*libl) + spcval(*libl *curlib) + expr(*yes) + prompt('Library') /* -------------------------------------------- */ /* To member */ /* -------------------------------------------- */ parm tombr *name 10 + dft(*file) + spcval(*file) + expr(*yes) + prompt('To member') /* -------------------------------------------- */ /* Replace member if it exist. */ /* -------------------------------------------- */ parm mbropt *char 8 + rstd(*yes) + dft(*replace) + values(*replace *add) + choice('*REPLACE, *ADD') + prompt('Replace or add records') _

CRTRTVDB/*------------------------------------------------------------------*/ /* Programmers Group & Management Resource Copyright 1998 */ /* */ /* \\\\\\\ */ /* ( o o ) */ /*------------------------oOO----(_)----OOo-------------------------*/ /* */ /* System name . . . : Programmer Tool */ /* Program name . . . : CRTRTVDB *//* Text . . . . . . . : Create RTVDBSRC */ /* Author . . . . . . : Alexander Nubla */ /* Description. . . . : Program to create RTVDBSRC utility */ /* */ /* Move the following member to the &Srclib */ /* 1. RTVDBSRC QCMDSRC */ /* 2. RTVDB1 QCLLESRC */ /* 3. RTVDB2 QRPGLESRC */ /* Modification Log: */ /* */ /* Date Task Programmer/Description */ /* 05/30/97 Alex Nubla */

9

Page 10: Printed RPG Quiz Technical

/* Created */ /* */pgm (&Objlib /* Object library */ + &Srclib ) /* Source library */ /* declaration */

dcl &Objlib *char 10 dcl &Srclib *char 10 crtclmod module(&Objlib/RTVDB1) + srcfile(&Srclib/QCLLESRC) crtrpgmod module(&Objlib/RTVDB2) + srcfile(&Srclib/QRPGLESRC) crtpgm pgm(&Objlib/RTVDB1) + module(&Objlib/RTVDB1 &Objlib/RTVDB2) crtcmd cmd(&Objlib/RTVDBSRC) + srcfile(&Srclib/QCMDSRC) + pgm(RTVDB1) EndPgm

Document Title RPG Subfile That Loads Subfile One Page at a TimeDocument DescriptionThe following example is an RPG program that loads the subfile one page at a time. As the user presses the Page Down key, it loads additional pages into the subfile.

Display File: A PRINT A CF03(03) A HELP A**************************************************************** A* HEADER RECORD TO BE AT TOP OF DISPLAY A**************************************************************** A R HEADER A OVERLAY A 2 3'HEADER' A 2 70DATE EDTWRD(' / / ') A 3 70TIME EDTWRD(' : : ') A**************************************************************** A* SUBFILE RECORD A**************************************************************** A R SF A SFL A ZIP 5 O 8 12 A CUST 20 O 8 28 A NAME 20 O 8 53 A**************************************************************** A* SUBFILE CONTROL RECORD A**************************************************************** A R SCTL SFLCTL(SF) A OVERLAY A SFLSIZ(08) A SFLPAG(07) A ROLLUP(90) A 31 SFLDSP A 32 SFLDSPCTL A 33 SFLEND A 34 SFLCLR A 35 SFLINZ A WDPOS 4S 0H SFLRCDNBR A 4 12'SUBFILE CONTROL' A 6 12'ZIP' A 7 12'-----' A 6 28'CUSTOMER' A 7 28'--------------------'

10

Page 11: Printed RPG Quiz Technical

A 6 53'NAME' A 7 53'--------------------' A**************************************************************** A* WRITE IF SUBFILE IS EMPTY A**************************************************************** A R EMPTY A OVERLAY A 8 12'THE SUBFILE IS EMPTY' A**************************************************************** A* FOOTER RECORD TO BE WRITTEN AT THE BOTTOM OF THE DISPLAY A**************************************************************** A R FOOTER A OVERLAY A 23 3'FOOTER'

Database File Source:

R FMT1 ZIP 5A CUST 20A NAME 20A

RPG Source:

FTESTPF IF E DISK FONEPGSFLCF E WORKSTN F RRN KSFILE SF * C Z-ADD0 RRN 40 **************************************************************** * * CLEAR SFL * **************************************************************** C MOVEA'0001' *IN,31 C WRITESCTL C MOVEA'0100' *IN,31 **************************************************************** * * LOAD FIRST PAGE OF DATA INTO SUBFILE. * **************************************************************** C EXSR LOAD **************************************************************** * * CHECK TO SEE IF SUBFILE HAS ANY RECORDS. * IF THERE ARE RECORDS THEN SET ON THE SFLDSP INDICATOR. * * IF THERE ARE NOT ANY RECORD IN THE SUBFILE THEN WRITE * THE EMPTY RECORD FORMAT. * **************************************************************** C RRN IFGT 0 C SETON 31 C ELSE C WRITEEMPTY C END **************************************************************** * * WRITE EVERYTHING TO THE DISPLAY. * **************************************************************** C *IN03 DOWEQ'0'

11

Page 12: Printed RPG Quiz Technical

C WRITEHEADER C WRITEFOOTER * POSITION THE SUBFILE TO THE PAGE THAT CONTAINS RELATIVE * RECORD NUMBER 1. C EXFMTSCTL C *IN90 IFEQ '1' C *IN03 ANDEQ'0' C *IN80 IFEQ '0' C EXSR LOAD C***************************************************************** C* ELSE C* ISSUE AN ERROR THAT YOU ARE ALREADY C* AT THE BOTTOM OF THE SUBFILE. USE THE C* MESSAGE SUBFILE EXAMPLE, SFLMSG, OR C* SFLMSGID. C***************************************************************** C ENDIF C ENDIF C ENDDO C MOVE '1' *INLR **************************************************************** * * LOAD SUBFILE * THIS PROGRAM LOADS THE SUBFILE ONE PAGE AT A TIME. * **************************************************************** C LOAD BEGSR C Z-ADD0 COUNT 20 C READ FMT1 80 C *IN80 DOWEQ'0' C COUNT ANDLE6 C ADD 1 RRN C ADD 1 COUNT C WRITESF C COUNT IFLE 6 C READ FMT1 80 C END C ENDDO C Z-ADDRRN WDPOS C *IN80 IFEQ '1' C SETON 33 C END C ENDSR

12

Page 13: Printed RPG Quiz Technical

Tips & Facts43. I would like to know difference between 1) *Loval and *Start 2) *Hival and *End Ans :LOVAL and *HIVAL are not specifically created for KEY/RECORD processing. *START and *END are are key-specific. *START always takes you to the first record in the key sequence, and *END takes to to the last (or after the last one depending on the logic). This works even when the key fields are in DESCENDING or ASCENDING sequence, which is at best confusing with *HIVAL/*LOVAL.Bob is correct. For example *HIVAL SETLL FILENAME might NOT position you at the end of the file, for example, when there are dupicate keys. However, *END is always at the end of the file.

*LOVAL can also have quirks, especially with descending keys, whereas *START always is a beginning of file. I most cases, therefore, it prob doesn't matter which you use. But on some cases, it does.

44. When to use LR & when not to use? Diff. LR & Return? Ans.: Return : will just return the control to the calling program. Without closing or initializing the local variables or will not clear the memory. Where as LR : will close all file and initialize all local variables and clear the memory used by that program. Setting on LR (Last Record) will close files and free resources occupy by the program.Initialization will occur on the next call to the program. Not setting on LR (in OPM programs) will keep the program in memory, keeps file open and pointers set, retains variable values, and prevents the *INZSR from being executed the next time the program is called, as well as INZ specified in your D-specs. As a rule, I never seton LR when a program will be called multiple times. This rule most definitely applied to a trigger program that could be called hundreds or possibly thousands of times.

45. How do I convert character to numeric

Ans : In OS/400 Version 5, Release 2 RPG IV was enhanced such that the %DEC and %INT built-in functions now support a character value on their first parameter. Simply specify the character field or literal value as the first parameter for %DEC, then indicate the length and decimal positions and the built-in function converts the character field to

13

Page 14: Printed RPG Quiz Technical

numeric. The %INT function works similar, except no length attributes are required since it only works with whole numbers.

D szWebFVal S 7A Inz('123.45') C Eval AmtDue = %DEC(szWebVal : 5:2)

Query/400:

Que : What are the advantages of OPNQRYFAns : a. Dynamically select records from files b. Dynamically access files in a specified key path c. Dynamically join files

Que :I would like to have the output report from Query named something other than QPQUPRFIL. Can this be accomplished anywhere within query? Or does it have to be set up in the CL that way? Ans : the Query/400 output report name depends on *prtf QPQUPRFIL. You can simlpy change output report (spool file) name by CL command: OVRPRTF FILE(QPQUPRFIL) SPLFNAME(your_new_name) Command OVRPRTF takes effect only for your job and you have to type this command before you run your query.Que : I have never used OPNQRYF before, but I need to maintain a program that uses this, so I hope you, experts, can help me out with this. The objective is to join files HIPF and NEPF with a format like QW001F so that the records can be accessed by the program via NEEAN field. The sequence of commands run by the RPG program by calling QCMDEXC goes like this: OPEN QW001F OPNQRYF FILE ((HIPF) (NEPF)) FORMAT (QW001F) KEYFLD NEEAN) JFLD ((2/NEAB 1/HIAB) (2/NEAN 1/HIAN) (2/NEAS 1/HIAS)) SEQONLY(*NO) JDFTVAL(*YES) COMMIT(*NO) OPNDBF FILE(QW001F) OPTION(*INP) COMMIT(*NO)/

just to test, I inserted here:CPYFRMQRYF FROMOPNID(HIPF) TOFILE(QTEMP/QW001F) MBROPT(*ADD) \...and it did produce the records... OVRDBF FILE(QW001F) TOFILE(HIPF) SHARE(*YES) OVRSCOPE(*JOB) /...here I am expecting the program will now use the GW001F access path... and should be able to get the records, but it can't find any... #NEEAN SETLL QW001F READ QW001F What should have been the correct way to refer to the opened query file? Please help! Thanks in advance, Ans : I assume that the file name in your F-spec is QW001F. The only thing that I do different is I do the OVRDBF prior to the OPNQRYF and I do not do OPNDBF2. I concur with Tfisher. OVRDBF to SHARE first, then OPNQRYF. OPNDBF is not needed since OPNQRYF is an OPNDBF with a subset of the data (or join or Whatever), so the file is open already, you do not need to open it again.3. Thanks for your replies. I tried removing the OPNDBF and putting the OVRDBF before OPNQRYF. Still there are no records on the READ.What sould have gone wrong? 4.What is the name of the file in your RPG program's F-spec?You should be following this sequenceOVRDBF ...OPNQRYF ...CALL RPG ...

14

Page 15: Printed RPG Quiz Technical

CLOF ...DLTOVR ...

If you are also doing a CPYFRMQRYF (or any other read of the file) before the RPG call, you will also need to do a POSDBF(*START). Because of the shared data path, the read does not restart at record 1 unless you position it there.5. How to join files using OPNQRYF command?OPNQRYF FILE(FILEA FILEB) FORMAT(JOINFMT) + JFLD((CMPY CMPY) (CUST# CUST#))

In your example JOINFMT is a existing file? JOINFMT is just something that I made up for this example, it is a format that would not exist in either of the two files I am joining.

When you join files you must give a format name in the FORMAT parameter. The format name may be any of the files being joined, but most people use a dummy format name that will be used to pass to the high-level language program. I have even seen people create DDS for the joined format. Either way, the format must be whatever your high-level language program is expecting. Also don't forget the override prior to the OPNQRYF command:OVRDBF FILE(JOINFMT) TOFILE(FILEA) SHARE(*YES)

Thank you once again! But I could not use dummy name for record format as it gave me error 'file not found in *LIBL'. I don't know the reason, because I had overridden the file with following command: OVRDBF FILE(JOINFMT) TOFILE(ABPF0001) SHARE(*YES) -----------------------------------------------------------------------------Then I created a file ABPF0006 and wrote following CL program: PGM MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(END)) OVRDBF FILE(ABPF0006) TOFILE(ABPF0001) + OVRSCOPE(*JOB) SHARE(*YES) OPNQRYF FILE((UAJIBAV/ABPF0001)(UAJIBAV/ABPF0002)) +FORMAT(ABPF0006) JFLD((1/EMEMNO + 2/SAEMNO)) MAPFLD((PFEMNO '1/EMEMNO') + (PFEMNM '1/EMEMNM') (PFDESG '2/SADESG') +(PFSARY '2/SASLRY')) CALL PGM(UAJIBAV/ABRP0010) CLOF OPNID(ABPF0001) DLTOVR FILE(ABPF0006) LVL(*JOB) END: ENDPGM -----------------------------------------------------------------

ABRP0010 RPG Code:

F* FABPF0006IF F 33 DISK E* I&FILE DS 33 I 1 30$FLD1 I 4 23 $FLD2 I 24 28 $FLD3 I 29 330$FLD4 C MOVE '0' *IN90 C *IN90 DOWEQ'0' C READ ABPF0006 $FILE 90 C *IN90 IFEQ '1' C LEAVE C ENDIF C $FLD1 DSPLY C $FLD2 DSPLY C $FLD3 DSPLY C $FLD4 DSPLY C ENDDO C MOVE '1' *INLR

15

Page 16: Printed RPG Quiz Technical

46. Can some one help me on how to get system data & time in free form RPG? If some one can help me in getting the free form RPG manual that would be great. Thanks Ans : 1. It's done in the D specs now:

D Date s d inz(*sys) datfmt(*usa)D Time s t inz(*sys) timfmt(*usa)

2. You can get the manual here: http://publib.boulder.ibm.com/pubs/html/as400/infocenter.htm Juan Carlos.

3. There is no "RPG Free" manual, the documentation for the RPG compiler directive and free form syntax is included in the RPG ILE manual. Go to the web site that Juan Carlos mentions. System date, time, and timestamp can be coded like this: SysDate = %Date; SysTime = %Time; SysTimeStmp = %Timestamp;

4. Is it possible to check a date retrieved from the a reade operation with the system date and iterate the the same process again to check the date as the key i am passing may have many records for it

5. /free read file; // Get next record dow not %eof(file); // Keep looping while we have // a record if %error; dsply 'The read failed'; leave; else; if %date=your_date; // your date is your date field do_something; // What you want to do

read file; endif; enddo;/end-free

47. Will u pls tell me the diff. in the simple query & query manager qry?Ans :What's the difference between Query/400 and QM Query. QM Query is based on SQL. You can write an SQL statement that generates the data for the output. Effectively you can replace OPNQRYF with QM Query & SQL offer a more readible solution

48. I want to write records in a local textfile. Ans : Use following code

16

Page 17: Printed RPG Quiz Technical

File definition [CODE] FDatei1 UF A F 117 DISK UsrOpn ExtFile(File) F Recno(cur) * D File S 128 Inz('C:/temp/TEST.DAT') D FileLen S 6 0 D Cur S 6 0 I Datei1 N S 01 I 1 6 O_knr I 7 36 O_nam1 I 37 66 O_strI 67 71 O_plz I 72 96 O_ortI 97 108O_kto At the End i have the outputODatei1 EAdd Neu OO_knr 6 O O_nam1 30 OO_str 30 O O_plz 5 OO_ort 25 O O_kto 12[/CODE] in the Klick procedure of the button have the following code c open Datei1 C eval O_knr = 4712 C eval O_nam1='Hans Testmaie2r' C eval O_str = 'Testweg 66' C eval O_plz = 11111 C eval O_ort = 'Testhausen2' C Except Neu when i check the output file, i see an empty file. There is no text in the file, but the blanks are there. That means : The record was written but there is no content. Please help me ! greets jogiAnS : I think the output def shouold look like this: whith the same endpositions as in the input statements ODatei1 EAdd Neu O O_knr 6 O O_nam1 36 O O_str 66 O O_plz 71 O O_ort 96 O O_kto 108 O_kto is blank in your output, so the first 12 bytes are blank, in your file should be the rest of O_nam1 (e2r) vom Hans Testmeier

49. I am having an assignment in which it is asked to display specific page of subfile. e.g. I am currently on 10th page of subfile, now if I wants to display 2nd page directly..... How should I do?Right now I have taken a input/output field in control record format, to specify the page to be displayed. How should I use this value to display specific page on LOAD ALL subfile.Is SFLRCDNBR or SFLCSRRRN useful in this case? Or any other keyword.Please, it is urgent. If possible try to elaborate your concept with an example...Ans: If your SFLPAG = 10, 2nd page should start on 11th record. Move this number to SFLRCDNBR and EXFMT again.

50. how do you access all members in pf? : WRKMBRPDM Ans : 1) OVRDBF FILE(XXXX) TOFILE(XXXXX) MBR(*ALL)

51. How many times can we open file in program?Ans :Use USROPN and you can open and close it as often as you want

52. how many records can be stroed when e specify *nomax? Ans :With the *nomax option, you can store *nomax records (I'll bet you always wondered what they ment by nomax).

17

Page 18: Printed RPG Quiz Technical

53. Pls somebody tell me how to find that weather there is data in PF in CL without defining file in CL? Also how to Maintain access path without using the opnqryf or Logical file or embedded sqlAns : Without defining... file in CL, Runqry / DSPFD command... can be executed in CL pgm or DSPPFM to check... whether data is present in PF or not. You can use RTVMBRD in CL and find the number of records in the file member

54. In how many categories for broke the system securities.I)General System Values II) Others System values related to security.III) System values that control password IV) system values that control audit map

55. How to retrieves the source of a CL program. Ans. RTVCLSRC56. How do I declare an array with a dynamic number of elements?Ans . In RPG IV, the new (V3 R7) ALLOC, REALLOC and DEALLOC operation codes can be used to allocate memory. This means that at run time, you can go out to the system and ask it to assign storage to the program that was not allocated to the program when it was evoked.These operation codes can be used to allocate memory up to 16MB. The allocation can be assigned to a pointer variable. In RPG IV, pointers have the data-type of asterisk (*). All that is needed is to allocate memory to a pointer that is used with the BASED keyword of the desired dynamic array. The example that follows illustrates this technique:.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++ D DynoArr S 7P 0 Dim(10000) based( pDynoArr) D nSize S 10i 0

.....CSRn01..............OpCode(ex)Extended-factor2++++++++++++++++++ C Eval nSize = %size(DinoArr) * 64.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq C Alloc nSize pDynoArr ** We now have enough storage allocated for 64 elements.

C Eval nSize = %size(DinoArr) * 70 C ReAlloc nSize pDynoArr ** We have changed the allocation to enough storage for 70 elements C* ... code to use the array goes here... C Dealloc(N) pDynoArr ** We have just returned the storage to the system. To increase or decrease the number of elements in the dynamic array, use the REALLOC operation code. Simply change the number of bytes that need to be allocated, and call REALLOC with the new size in Factor 2 and the original pointer variable in the Result field. REALLOC allocates new storage of the size specified, and copies the original data to that new location. Then it frees ("deallocates") the original storage.IMPORTANT: Always remember to DEALLOC anything you ALLOC. That is always free up memory that you have allocated otherwise memory leaks will be created.

18

Page 19: Printed RPG Quiz Technical

If you are not on V3 R7, you can still use dynamic memory by calling one of the system APIs or linking into the QC2LE binding directory and calling the C runtime MALLOC and DEALLOC functions.

How do I do concatenation in RPG IV, like I do in CL?In the initial release of RPG IV, the plus sign can be used to do simple concatenation. When the expression of any of the enhanced operation codes includes string expressions, then the plus sign is considered a concatenation operator. In later release of RPG IV, the built-in function %EDITC can be used to allow numeric fields to participate in simple concatenation.The example below illustrates the basic concatenation (line 4) and the enhancement introduced in OS/400 V3 R7......FFILENAME++IFEASFRlen+LKeylnKFDEVICE+.Functions++++0001 FCUSTMAST IF E K Disk.....CSRn01..............OpCode(ex)Extended-factor2+++++++++++++++++++++++.....CCRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq0002 ** RPG IV on OS/400 V3 R1 and later...0003 C CustNo Chain CustMast 730004 C Eval Msg = CustName + ' is ' + CM_Status 0005 ** RPG IV on OS/400 V3 R2 and V3 R7 and later...0006 C Eval Msg = 'Customer: ' + %EditC(CustNo:'Z') +0007 C ' is ' + CM_StatusIn addition, the traditional RPG IV CAT operation code can be used for concatenation.

57. Are there any useful C Runtime APIs that I can call from RPG IV?There are several C runtime APIs available to the RPG IV developer. In OS/400 version 3, release 1 the scope of these APIs is limited.The CALLB operation code can be used to directly call the C runtime APIs, provided they don't require "pass by value" parameters.In V3 R2 and later, parameters can be passed by reference or by value. In addition, Prototypes are supporte for calling procedures written in RPG IV or other languages.The current list of C-related runtime functions is large. To support these functions in your RPG IV programs you need to compile the program so that it runs in a normal activation group, and binds to the C runtime library. A binding director is conveniently provided for just this purpose. For example:CRTBNDRPG pgm(myPgm) DFTACTGRP(*NO) BNDDIR(QC2LE)By specifying DFTACTGRP(*NO) and BNDDIR(QC2LE), you open up your RPG IV program to the world of C runtime functions. These functions include high-level math and time formatting routines. See the RPG Developer Network News articles on integrated these functions in RPG IV for more information.Another cool thing about QC2LE is that the ILE C/400 runtime includes the full set of open AS/400 MI instructions. That is the AS/400 assembly language can be called directly from RPG IV by prototyping their C/400 functions. For example, to call the Convert Characters to Hexadecimal Symbols MI instruction, you would call the 'cvthc' C runtime function. For example:The following RPG IV code should compile on any version of OS/400 that includes RPG IV......DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++ D szCharVal S 20A Inz('ABCDEFG') D szHexVal DS D szHex1 LIKE(szCharVal) D szHex2 LIKE(szCharVal)

19

Page 20: Printed RPG Quiz Technical

D nCharLen S 9B 0 .....CSRn01..............OpCode(ex)Extended-factor2++++++++++++++++++ ** if you want to avoid converting trailing blanks, use this stmt. C ' ' CheckR szCharVal nCharLen

** or if you want to convert trailing blanks, use this stmt. C Eval nCharLen = %size(szCharVal) * 2

.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq ** This converts '123' to 'F1F2F3' C CALLB 'cvthc' C Parm szHexVal C Parm szCharVal C Parm nCharLen ** This converts 'F1F2F3' to '123' C CALLB 'cvtch' C Parm szCharVal C Parm szHexVal C Parm nCharLenJust a few things to remember when using the C runtime APIs.

The names are case-sensitive. That is 'cvthc' must be specified in lower case or it will not be found.

These functions are located in the OS/400 C-runtime library and must be bound using the QC2LE binding directory.

Parameters that require pass-by-value restrict the API to being called with newer releases of RPG IV, via procedure prototypes.

C functions that have return values cannot be called by RPG IV under OS/400 version 3, release 1.

Until you move to V3 R2 or, even better, V3 R7, the number of interfaces that can be accessed by RPG IV is limited. In fact, the HexToChar, CharToHex functions are about all that are useful.

Under later releases of RPG IV, procedure prototypes allow access to all of the C runtime functions. This includes those nice little date and time formatting functions, such as asctime

58. Can you clear up the confusion in the different releases of RPG IV and OS/400 and ILE?Ans . RPG IV is the next generation of the RPG language. RPG III is the original version of AS/400 RPG/400. The name "AS/400 RPG/400" is that given to the IBM compiler package for distribution on the AS/400. This compiler package compiles various versions of RPG, including RPGII and at least two releases of RPGIII.As of OS/400 Version 3 release 1, IBM changed the name of this compiler package to "AS/400 ILE RPG/400". The reason for this name change was to identify that fact that the compile now includes a version of RPG that targets the Integrated Language Environment (ILE), that is RPG IV.ILE was first shipped in OS/400 Version 2, Release 3. However, only the C language compiler produced code that targeted this environment. First, a word about ILE.ILE is the new, "native" runtime environment for Programs, on the AS/400. Under OS/400 Version 2 Release 3, IBM introduced a new program model. This basically means that new features and interfaces became available. However, IBM did not just port some runtime environment to the OS/400 operating system, it actually re-wrote code, and wrote new code that, essentially, changed the way OS/400 works. This new code provides support for a mixed set of high-level languages.Previously, RPG and CL had their own little runtime environment, COBOL had it's own, C had it's own, and so on. Under ILE, all programming languages run in ILE. The same "environment" is used for COBOL, C, RPG and CL.However, to take advantage of ILE, new compilers needed to be created. As for RPG, rather than convert the existing RPGII and RPGIII compilers,

20

Page 21: Printed RPG Quiz Technical

IBM, who was designing a new version of RPG anyway, decided to target ILE with the new compiler. This would simultaneously provide a new version of RPG and an ILE targeted compiler.

Names Are ImportantA good friend of mine once said, "names are important" in the programming world. If a field is called "Rhinoceros", does it represent its use or purpose? Okay, so perhaps in traditional RPG "Iguana" is a better choice for this example. (Shorter name.)During the development of RPG IV, two distinct issues arose. First, the internal name for RPG IV, was "ILE RPG". This was not a code name, but rather the name IBM used to refer to the new compiler. After all, it was targeting ILE, why not refer to it as "ILE RPG"? Second, the re-architecture of RPG came into question.Unfortunately, the internal name "ILE RPG" began to be leaked out to the public. Several magazine writers and IBMers not involved in the development of RPG IV continued to use the term "ILE RPG" when referring to RPG IV. I suppose these people still refer to the AS/400 as SilverLake or perhaps even Olympic.Then when IBM announced the compiler package or product name as "AS/400 ILE RPG/400" it only added to the confusion. IBM dropped the ball when promoting the RPG IV name. They are, after all, set up to market their products with their product names. The name of one programming language included in a product that contains nearly seven full compilers isn't high priority.RPG IV is the version of RPG that targets ILE. OS/400 V3R1 compatible RPG IV can also target what is now called "the original program model" or simply OPM. OPM is just a name that has been given to the original runtime environment of RPG and CL under OS/400. This is the environment in which RPGIII and CL run. Under ILE, however, the original native environment is emulated, that is, ILE isn't an environment at all, it is native OS/400, whereas, OPM is now an environment under ILE. Some very clever programming and design went into this, don't you think? Not very many other operating systems, if any, provide this kind of continuity.

59. RPG IV -- Release what?Ans . RPG IV was first shipped with OS/400 Version 3, Release 1. This is now referred to as RPG IV release 1. But don't worry about remembering releases of RPG IV.Under OS/400 Version 3, Release 6, IBM enhanced RPG with procedures, many more built-in functions, and several new data types. This is referred to as RPG IV release 2.Then, OS/400 Version 3, Release 2 was announced. It brought the original release of RPG IV (on the CISC boxes) up to the same level as RPG IV under V3R6. Are you confused yet? Me too!Under OS/400 Version 3, Release 7, IBM added a couple of enhancements, most notably they increased the length of a field name to a number so large not even magazine authors that don't write real-world code could complain about it anymore. They also added one or two new data types, rounding out RPG IV so that it supports all AS/400 data types, except variable length fields. This version of RPG IV is known as RPG IV Release 3.The following table identifies the current releases of RPG IV. Note that RPG IV releases do not necessarily coincide with releases of the operating system.RPG IVRelease

OS/400 Version/Release

CISC or RISC

1 V3 R1 CISC2 V3 R6 RISC2 V3 R2 CISC3 V3 R7 RISC

21

Page 22: Printed RPG Quiz Technical

4 V4 R2 RISC4 V3 R5 (speculation)

See note 1CISC

5 V4 R3 RISC5 V4 R4 (February 1999) RISC6 V4 R5 (Summer 2000) RISC

NOTE 1: It is speculated that IBM may ship a final "clean up" release of OS/400 for CISC that would included a large level of compatibility with OS/400 V4 R5. The release levels of RPG IV are only important if you want to keep track of that kind of thing. One disappointing issue is that unless you stay on the most current release of OS/400, you don't get all the cool new features in RPG IV. Even if you stay current, you can't target prior releases if you use any of the new features. In fact, even if you use a new feature that doesn't depend on an operating system enhancement, it can't be used for back releases. This is because of the way the TGTRLS (target release) feature has been implemented. Basically, if you're on V4 R2 and you do a TGTRLS(V3R2M0) the compiler calls the actual compiler for V3 R2. It doesn't have a built-in syntax checker that says "This feature requires an OS/400 upgrade so don't allow it, or this one is okay so accept it." It iscalling the same "binary" compiler code that is on any old V3 R2 system.Which means, for example, that if you want to take advantage of the new compiler directives, but you often have to target a prior release, you can't use those directives. For example, /IF DEFINED does nothing for the executable code that's generated, but is not supported when TGTRLS(V3R2M0) is specified. ;( Bummer!So now we know about RPG IV release levels and how the term "ILE RPG" got into our vocabulary. So let's clear up another term, the name of the RPG language. The big one is the term "RPG/400". There is not programming language called "RPG/400". The language most often called "RPG/400" is RPGIII. However, back in the System/38 days, the System/38 RPG language was called RPGIII. When the AS/400 was announced, programmers wanted to give themselves an advantage on their résumé. So they began calling AS/400 RPGIII, "RPG/400". Then to make matter worse, when RPG IV was announced, programmers thought that the number "IV" in "RPG IV" was less than the "400" in "RPG/400". So they decided to call RPG IV, "ILE RPG". Well let's set the record straight. The table below lists the RPG language names, their incorrect name, and the proper name.Commonly used Wrong Name

Formal Name Proper (correct) Name

RPG/36 System/36-compatible RPGII RPGIIRPG/38 System/38-compatible

RPGIIIRPGIII

RPG/400 RPGIII RPGIIIILE RPG RPG IV RPG IV

60. How does the CONST keyword work with Procedure parameters?

Ans . If you are certain that the called procedure will NOT modify a parameter, the CONST keyword can provide several benefits.

1. It automatically converts a field of a similar data type, to the length and type required by the parameter.

What this means, is say a parameter is a 15 position pack field, with 5 decimals. Normally, you'd have to specify a Pdk(15,5) field for the parameter. However, if the parameter is read-only, you can specify CONST on the Prototype and Procedure Interface for the

22

Page 23: Printed RPG Quiz Technical

parameter. When you do this, the compiler automatically converts the value (say it's a literal of 27) to the size and type required by the parameter. This works really cool with DATE fields. A date for any format can be passed as a parameter value when that parameter value is CONST.

2. Performance is improved because the compiler can generate more optimized code for the CONST parameter.

CONST can be used on calls to procedures or programs. We use it all the time when calling QCMDEXC from within RPG IV. All three parameters of the QCMDEXC program are CONST values. The example code below can be used as the PROTOTYPE to call QCMDEXC from within RPG IV. To call it using this prototype, specify something like: CALLP run('addlible myLib' 14) in your calculation specs......DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++ D Run PR ExtPgm('QCMDEXC') D cmdstr 3000A Const Options(*VarSize) D cmdlen 15P 5 Const D cmdDbcs 3A Const Options(*NOPASS)Note: if you're using CodeStudio or IBM's Code/400 as your RPG IV editor under Windows, you could simply highlight the above source code within your Internet Browser, and copy it to the Windows clipboard. Then activate CodeStudio (or Code/400) and use the Paste function to insert the code directly into the editor. Pretty cool, huh? <g>

What's new in OS/400 Version 5 RPG IV?So much is new in RPG IV with OS/400 Version 5, that I wrote an article about it. Read my article about the enhancements to RPG IV in OS/400 Version 5.There are a few significant enhancements in RPG IV in OS/400 Version 4, Release 4.

The %CHAR built-in function has be fixed. It now functions like it was supposed to in the first place. You can wrap a numeric value in %CHAR and a nicely edited character form of the number is returned. The edited form includes the decimal, trimmed off leading blanks, and a negative sign.

The FOR loop provides a free-format version of the DO operation code. With the FOR operation, you can begin a loop operation and continue iterating through the loop until a variable equals a limit value. The syntax for the FOR operation is enhanced with the TO, BY and DOWNTO keywords. The TO operation indicators the upper limit for the looping, while the BY keyword identifies the increment value for the loop counter. Alternatively, you can specify the DOWNTO keyword to loop backwards from a large value to a small value.

The OPENOPT keyword is added to the Header specification. This keyword can be used along with its one and only parameter *INZOFL to cause overflow indicators to be set off when their corresponding printer file is closed and then re-opened during the program. So use OPENOPT(*INZOFL) when needed.

In subroutines, the LEAVESR operation can now be used to exit a subroutine immediately. Effectively this is a "glorified goto" operation that branches to the ENDSR statement of a subroutine.

23

Page 24: Printed RPG Quiz Technical

61. How do I handle the error and LR indicator on a CALL, when using CALLP?Ans . The short answer is, you can't. The long answer is, it depends on the OS/400 release level. In releases prior to OS/400 V4 R2, there is no way to detect the LR situation. Errors are trapped either by specifying the PSSR subroutine, or using an ILE error/event handling API. In V4R2 and later, its a little easier. RPG IV supports the %ERROR built-in function. This built-in allows you to test the result of the CALLP operation. Unfortunately, we have to use a silly "E" operation extender. Apparently it is easier to code CALLP(E) and then check the status of %ERROR for a *ON or *OFF condition than it is to not use (E) and still check %ERROR. %ERROR is only set when the E operation extender is used. ;(As for checking if the called program set on LR before returning, the use of CALLP does not provide this capability.

62. How do I enable a "workstation time-out" feature in RPG?Ans . There are five things required to provide a time-out option on any interactive workstation file. This capability allows an RPG program to receive control before an end-user presses a Function key or Enter. Some of the uses for this kind of function include:

Providing a marquee for a schedule via a subfile

Update the time displayed on the workstation at regular intervals

Refresh the information, such as a news display, periodically

As mentioned, there are five things required to achieve workstation time-out. Those five things are:

1. Add the INVITE keyword to the Workstation display file DDS. This is a file-level keyword.

2. Use the WAITRCD parameter of CRTDSPF to set the desired time-out period.

3. Add the MAXDEV(*FILE) keyword to the File specification for the Workstation device file.

4. Write the desired display file formats to the display using the normal methods.

5. Use the READ operation code to read Display File name, not the Record format name.

You must avoid using EXFMT to the display file as this operation code does not support workstation time-out.

F Marquee CF E WORKSTN MAXDEV (*FILE) F SFILE(detail:rrn) C Write Header C Write Footer C Do 12 rrn C Write Detail C enddo C Write SFLCTLFMTC Read Marquee

63. What Binding Directory Do I need to bind to when using CGI RPG IV?The QTCP library contains the service program named QTMHCGI which includes access to all the necessary objects to accessing any Qtmh* API. So set the BNDSRVPGM parameter to QTMHCGI in QTCP.

24

Page 25: Printed RPG Quiz Technical

If V4R2 or earlier use QTMHCGI service program:>> BNDSRVPGM (QTCP/QTMHCGI)If later than V4R2 use:>> BNDSRVPGM (QHTTPSVR/QZHBCGI)

0000.01 0000.02 * Test program for source highlighting 0000.03 01.0 FQRPGLESRC UF F 112 DISK EXTFILE('QGPL/QRPGLESRC') 02.0 0001.01 F EXTMBR('TEST') 03.0 0002.00 04.0 0003.00 D Normal C CONST(X'20') 05.0 0004.00 D Reverse C CONST(X'21') 06.0 0005.00 D Highlight C CONST(X'22') 07.0 0006.00 D ReverseHi C CONST(X'23') 08.0 0007.00 D Underline C CONST(X'24') 09.0 0008.00 10.0 0009.00 IQRPGLESRC NS 01 11.0 0010.00 I 1 112 Record 12.0 0011.00 I 18 18 LineType 13.0 0012.00 I 19 19 Star 14.0 0013.00 15.0 0014.00 /free 16.0 0015.00 17.0 0016.00 dou %EOF(QRPGLESRC); 18.0 0017.00 read QRPGLESRC; 19.0 0018.00 if %EOF(QRPGLESRC); 20.0 0019.00 leave; 21.0 0020.00 endif; 22.0 0021.00 if Star = '*' and LineType = *BLANK; 23.0 0022.00 LineType = Highlight; 24.0 0023.00 except Upd; 25.0 0024.00 endif; 26.0 0025.00 enddo; 27.0 0026.00 28.0 0027.00 *INLR = *ON; 29.0 0028.00 return; 30.0 0029.00 31.0 0030.00 /end-free 32.0 0031.00 33.0 0032.00 OQRPGLESRC E Upd

0033.00 O LineType 18

Dhiroo Bhai :

1. MAKING THE TRANSITION TO FREE-FORMFree-form RPG is a controversial topic. I've received a number ofMessages from readers who feel strongly that I should provide my codeSamples in free-form RPG -- but I've also received messages fromPeople who don't like it.

Before starting to include free-form code in the newsletter, I thoughtit would be a good idea to introduce some of the aspects of free-formRPG to the readers. Unfortunately, I don't have nearly enough space tocover everything, so I will show some samples to get you started.

HOW TO CODE FREE-FORM STATEMENTSFree-form code only replaces the calculation specifications ("c-specs") of your program. The H,F,D,I,O, and P specs are still coded in

25

Page 26: Printed RPG Quiz Technical

the same way that they would be if you were writing traditional fixed-form code.

Instead of coding a form type in position 6 of every record, free-formcode is identified as a block. You code the "/free" compiler directivein position 7 of the record to start the block, and you code the"/end-free" compiler directive when you want the block to end. Allfree-form statements are typed in columns 8-80 of the record.

Every free-form statement ends with a semi-colon. If no semi-colonappears at the end of a line of code, the compiler will assume thatthe statement is not finished and will interpret the next line as partof the same statement.

The following is a very simple RPG program that uses free-form:

D msg s 50A D wait s 1A

/free

eval msg = 'Hello World'; dsply msg ' ' wait;

eval *inlr = *on;

/end-free

Just to make it absolutely clear -- the semi-colon ends everystatement. It does not matter where one physical line begins andanother ends. For example, the following statement is ugly, butperfectly valid:

eval *inlr = *on;

In free-form, the op-code is always specified first in each statement,followed by the factor1, factor2, and result fields. If a particularop-code does use the factor1, factor2, or result field, it is simplyomitted.

The following is a traditional C-spec for the chain op-code:

C RRN chain MyFile

This is the free-form equivalent:

chain RRN Myfile;

THE EVAL AND CALLP OP-CODES ARE SPECIALYou do not have to specify an op-code when coding an EVAL or CALLPoperation. The following lines of code are equivalent:

eval msg = 'Hello World';

msg = 'Hello World';

26

Page 27: Printed RPG Quiz Technical

MANY OP-CODES HAVE BEEN REMOVEDOne of the most controversial aspects of free-form RPG is that many ofthe op-codes that you have in traditional fixed-form RPG have beenremoved. For the most part, they were removed because of theexpressions that you have available in the EVAL statement.

The "Websphere Development Studio ILE RPG Reference" manual in theInformation Center will tell you if an op-code is supported in free-form, and if not, it will suggest an alternative. For example, if youlook up the TIME op-code in the manual, you'll see that it says:

"Free-Form Syntax: (not allowed -- use the %DATE, %TIME, or %TIMESTAMPbuilt-in function)"

SAMPLE FREE-FORM REPLACEMENTSIn most cases where fixed-form op-codes were removed from free-formRPG, an expression or built-in-function (BIF) can be used instead.Most of the things that I'm going to explain here aren't onlyavailable in free-form and on the traditional C-specs using the EVALop-code.

Since RPG IV was introduced in V3R1, it has been possible to do mathoperations using expressions in the EVAL op-code. These sameexpressions work nicely in free-form.

Here are some typical math operations:

C A ADD B TOTAL1 C A SUB B TOTAL2 C A MULT B TOTAL3 C X DIV Y Z

And this is how you'd code them as expressions:

Total1 = A + B; Total2 = A - B; Total3 = A * B; Z = X / Y;

Starting in V5R2, there are new operators in EVAL statements that canbe used when performing a math operation that affects itself.

C ADD 1 COUNT1 C SUB 1 COUNT2 C MULT 2 COUNT3

They can be coded with the special operators as follows:

COUNT1 += 1; COUNT2 -= 1; COUNT3 *= 2;

Prior to V5R2, you could accomplish the same thing by doing thefollowing:

COUNT1 = COUNT1 + 1; COUNT2 = COUNT2 - 1; COUNT3 = COUNT3 * 2;

27

Page 28: Printed RPG Quiz Technical

It's often useful to be able to get the remainder of a divisionoperation. For example, if you want to know the remainder of X dividedby Y, you'd traditionally code the following:

C X DIV Y UNUSED C MVR R

With the %REM() BIF, you no longer need to do division first -- andyou no longer need to define a variable that you don't need elsewhere.You can simply code this:

R = %REM(X : Y);

The Z-ADD and Z-SUB op-codes were used in the old days to assign anumeric value to a variable.

c z-add 15 A c z-sub 99 B

In free-form RPG, you could do the same thing with an expression:

A = 0 + 15; B = 0 - 99;

Though, it seems to me that it makes more sense to just do a simpleassignment:

A = 15; B = -99;

Date operations are now also done with expressions even though datesare relatively new to the language.

c OrigDate adddur 7:*DAYS MyDate c OrigDate subdur 1:*MONTHS YourDate c extrct MyDate:*Y Year

In an expression, you need to tell it that you're adding a number ofdays or subtracting a number of months by wrapping the number in the%DAYS or %MONTHS BIFs:

MyDate = OrigDate + %days(7); YourDate = OrigDate - %months(1); Year = %subdt(MyDate: *Y);

There are also BIFs called %YEARS, %HOURS, %MINUTES, %SECONDS, and%MSECONDS that can be used in the same manner.

You can use special operators, += and -= with date operations as well.For example, to replace the following:

c adddur 7:*DAYS MyDate c subdur 1:*MONTHS YourDate

You can code this:

MyDate += %days(7); YourDate -= %months(1);

28

Page 29: Printed RPG Quiz Technical

For many of the op-codes, there are BIFs that directly replace them.The following op-codes can be directly replaced with BIFs: ALLOC,CHECK, CHECKR, LOOKUP, REALLOC, SCAN, SHTDN, SQRT, SUBST, XLATE, andXFOOT.

One nice feature of a BIF is that you can use it anywhere you can usean expression, including on IF, WHEN, DOW, or DOU statements.

For example, a loop that was once coded like this:

C SHTDN c dow *IN99 = *OFF

... The code here is run until the operator shuts the program ... down with ENDJOB, ENDSBS, PWRDWNSYS

C SHTDN c enddo

Can now be coded like this:

/free

dow not %shtdn();

... The code here is run until the operator shuts the program ... down with ENDJOB, ENDSBS, PWRDWNSYS

enddo;

/end-free

Or perhaps a better example is using the XFOOT operation for validitychecking. It's handy to be able to use it directly in an IF statement.Consider the following example:

c xfoot MyArray Total c if Total = 0 c eval ErrMsg = 'You have to put at ' + c 'least one value in the '+ c 'array!' c exsr HandleError c endif

I think it's easier to read when it's coded like this:

if %xfoot(myArray) = 0; ErrMsg = 'You have to put at least one value into ' + 'the array'; exsr HandleError; endif;

The CALL, CALLB, PLIST, and PARM op-codes are replaced withprototypes. Explaining all the uses of prototypes is beyond the scopeof this article, but I will include one quick code sample.

Here is the traditional syntax:

29

Page 30: Printed RPG Quiz Technical

C CALL 'YOURPGM' C PARM OrderNo 5

The following illustrates how you do the same thing in free-formatcode with a prototype. Note that 'YOURPGM' does not have to be writtenin free-format, or even in RPG IV, for this code to work.

D YourPgm PR ExtPgm('YOURPGM') D OrderNo 5A

/free YourPgm(OrderNo);

/end-free

KEYLISTSThe KLIST and KFLD op-codes are gone, replaced by two features, theability to use a data structure for your keylists, and the ability tolist multiple keys on the file operation itself.

I've never liked keylists because I don't like having to rememberthings. When I'm 200 lines of code into the program and I see that theprogram is using KEY01 to chain to a file, I don't want to have tosearch the program for KEY01 to find out which fields are being used.For the same reason, I also don't use data structures as keys, and Idon't see any advantage to them.

My preference is to include the keys on the file operation itself, asillustrated in this sample code that adds up each invoice for a day'sbusiness:

/free

DailyTotal = 0;

setll (MyDate) INVHEADER; reade (MyDate) INVHEADER;

dow not %EOF(INVHEADER);

InvTotal = 0;

setll (InvDate: InvNo) INVDETAILS; reade (InvDate: InvNo) INVDETAILS;

dow not %EOF(INVDETAILS); InvTotal += Price * Qty; reade (InvDate: InvNo) INVDETAILS; enddo;

InvTotal -= Discounts; InvTotal += Taxes; DailyTotal += InvTotal;

reade (MyDate) INVHEADER; enddo;

/end-free

30

Page 31: Printed RPG Quiz Technical

COMBINING FIXED-FORM AND FREE-FORM IN ONE PROGRAMIt's fine to mix the two coding styles in the same program, but it canmake the code hard to read if you keep switching back and forthbetween the two different styles.

My suggestion is that you do not mix fixed-form and free-form RPG inthe same routine. Make each procedure, subprocedure, or subroutineeither all free-form, or all fixed-form.

INDENTINGWell-written free-form code is easier to read than fixed-form becauseit can be indented -- but poorly written free-form is more difficultto read than fixed form. Your shop should develop standards for howyou want the code to be formatted.

Something that's important to remember is that the lessons you'velearned over the years are still important. Spacing before and afteran IF group will still make it easier to read in free-form. Keepingthe number of statements between an IF and ENDIF to a minimum willstill help.

Indenting is an additional tool that helps to improve readability.Three or four spaces are all you need to indent. If you indent toomuch, you'll run into problems with the code not fitting nicely on thescreen. If you indent too little, it'll be difficult to see where thenesting levels are.

The code sample above that shows totalling up invoices for a day'sworth of business is a good example of how I like to indent my code.

31