Last Updated on 27 April 2020 by Roberto De Pedrini
Part 1 of this FAQ, the first 10 Questions and Answers are available at this link: RPG – FAQ & Howtos (IT Part.1)
RPG-FAQ-013: Programming in RPG / Free – A Beginner’s Tutorial
For those who start working with RPG Free and Full-Free there are these two excellent guides:
- Coding in Free-Form RPG IV – a beginner’s tutorial By Barbara Morris on IBM Developerworks
- Coding in Free-Form RPG IV – a beginner’s tutorial By Barbara Morris on Midrange.com
RPG-FAQ-012: Reduced expressions – short expressions (+ = …)
In the assignments of value to the variables in RPG Free we can use the “short expressions”, stolen from the language C … they are comfortable because you save something in writing the code but you have to be careful not to confuse the position of the equal sign (=) …. for example “i + = 1” increases the value of i by one while “i = + 1” sets i to the value 1 positive!
i = i + 1; ---> equals ---> i + = 1; i = i-1; ---> equals ---> i- = 1; r = r * 2; ---> equals ---> r * = 2; r = r / 2; ---> equals ---> r / = 2; We can also use these functions by managing the round eval (h) r / = 2;
RPG-FAQ-013: Datastructure Likerec vs DS extname template
This was discussed in October 2019 on the Midrange.com RPG-L discussion group: what is the difference between the two ways of defining a DS as a qualified template:
Method 1 dcl-f CUSTFILE keyed template qualified; dcl-ds cust_t likeRec (CUSTFILE.CUSTFILER) template; dcl-s custName like (cust_t.name); Method 2 dcl-ds cust_t extName ('CUSTFILE') qualified template end-ds; dcl-s custName like (cust_t.name);
The two different methods come to the same result … in both cases we can define the “custName” variable as “cust_t.name” external field taken from the “CUSTFILE” table … we could say that the method with extName does not oblige us to define our file in the ‘F’ (or rather DCL-F) specifications.
Another difference between the two methods lies in the syntax of the “DCL-DS” definition specifications: with EXTNAME we must indicate END-DS while with LIKEREC no: perhaps not everyone knows that with DLC-DS ExtName we can add fields outside the DS , let’s see an example:
dcl-ds myds extname (mytable); extraFld1 char (10); extraFld2 char (15); end-ds;
RPG-FAQ-014: Different COMMIT LEVELs in the same source?
From a question on the Midrange.com mailing list:
I have a program that has two different steps … in the first it creates a table in QTEMP (which is possible only with commit = * none) and in the second step it executes a JSON_TABLE reading the JSON document with the get_CLOB_from_file () function (which is not possible if commit = * none): it is possible to change the commit level in the same program?
The answer comes from the forum:
- Check isolation level commit in individual SQL statements: something like INSERT INTO QTEMP.MYFILE () WITH NC
- Divide the logic into two different programs or service programs with each its commit level
- Use commit to “close” transactions and use isolation level between commits
- exec sql commit; // end running transaction
- exec sql set transaction isolation level ur; // change to commit * CHANGE
- // do your commited stuff
- exec sql commit; // end transaction
- set transaction isolation level n / a; // change to commit * NONE
- // do some uncommited stuff
- exec sql commit;
- set transaction …
- Instead of creating the temporary table with CREATE TABLE QTEMP.XXX it is preferable to use DECLARE GLOBAL TEMPORARY TABLE X … which has the advantage of being able to use the COMMIT control, which is not possible for the QTEMP tables.
RPG-FAQ-015: Timestamp precision in RPG
RPG %Timestamp BIF resolve only milliseconds: if you need more granularity you can use the QWCCVTDT API (up to microseconds) or SQL Embedded. Have a look at this simpe RPG code by Vernon Hamberg
dcl-s tstmp06 timestamp; dcl-s tstmp12 timestamp(12); dcl-s tstmp06from12 timestamp; dcl-s tstmp12from06 timestamp(12); dcl-s tstmp06sys timestamp; dcl-s tstmp12sys timestamp(12); dcl-s tstmp06s timestamp; dcl-s tstmp12s timestamp(12); dcl-s tstmp06sfrom12 timestamp; dcl-s tstmp12sfrom06 timestamp(12); // Use BIF timestamp alone tstmp06 = %timestamp; tstmp12 = %timestamp(*sys : 12); tstmp06from12 = %timestamp(*sys : 12); tstmp12from06 = %timestamp; // Use *SYS in BIF tstmp06sys = %timestamp(*sys : 6); tstmp12sys = %timestamp(*sys : 12); // Use SQL current timestamp exec sql set :tstmp06s = current timestamp; exec sql set :tstmp12s = current timestamp(12); exec sql set :tstmp06sfrom12 = current timestamp(12); exec sql set :tstmp12sfrom06 = current timestamp; *inlr = *on;
Here the results:
> EVAL tstmp06 TSTMP06 = '2019-12-08-04.04.22.647000' > EVAL tstmp12 TSTMP12 = '2019-12-08-04.04.22.647000000000' > EVAL tstmp06from12 TSTMP06FROM12 = '2019-12-08-04.04.22.647000' > EVAL tstmp12from06 TSTMP12FROM06 = '2019-12-08-04.04.22.647000000000' > EVAL tstmp06sys TSTMP06SYS = '2019-12-08-04.04.22.647000' > EVAL tstmp12sys TSTMP12SYS = '2019-12-08-04.04.22.647000000000' > EVAL tstmp06s TSTMP06S = '2019-12-08-04.04.22.647548' > EVAL tstmp12s TSTMP12S = '2019-12-08-04.04.22.647802819335' > EVAL tstmp06sfrom12 TSTMP06SFROM12 = '2019-12-08-04.04.22.647935' > EVAL tstmp12sfrom06 TSTMP12SFROM06 = '2019-12-08-04.04.22.648147000000'
RPG-FAQ-016: How to flip an indicator in RPG
Of course we are talking about ind … variables, not numerical indicators that I hope you will no longer use in the new RPG sources. It’s a simple thing, maybe it’s not even worth dedicating a FAQ on this Blog … but I realize that I’ve often found myself in the condition to “invert” sign of an indicator (the classic function key that activates / deactivates a setting) and I’ve often used 5 lines of code instead of only one: have a look at the following code:
dcl-s view Details ind inz(*off); // Long version, up to five lines of code ... // Flip viewDetails indicator if viewDetails=*on; viewDetails=*off; else; viewDetails=*on; endif; // Here the short version ... one row only! ... // Flip viewDetails indicator viewDetails= not viewDetails;
RPG-FAQ-017: How to export source to GIT
If you need to export your source files to GIT you can schedule a simple job like in this Niels Liisberg’s Github Gist:
Niels Liisberg: Export Source to GIT
Or you can try this great Richar Shoen’s utility “IforGit”: you can work with your source in a Git repo with RDI and SEU too.
RPG-FAQ-018: *PCML and Java Procedure dentro RPG
To avoid error “RNF0302 – Errors were found while generating the program information to be placed in the module” when you have an RPG with PGMINFO(*PCML:*MODULE) and some Java Procedure in the source you have to use PGMINFO(*NO) keyword on every Externa Java Procedur – Program Interface PI:
ctl-opt pgminfo(*PCML: *MODULE: *DCLCASE);
Dcl-Pr myrpgws ExtPgm('MYRPGWS');
*n Char(8) Const;
*n Char(8) Const;
*n Char(1) Const;
*n Char(1000);
End-Pr;
*
Dcl-Pi myrpgws;
InSundayDate Char(8) Const;
InSaturdayDate Char(8) Const;
InFinalFlag Char(1) Const;
OutResults Char(1000);
End-Pi;
...
...
Dcl-Proc newString Export;
D newString PI O Class(*java: jStrConst) PGMINFO(*NO)
D pString 32767A Const
....
RPG-FAQ-019: *PCML and varying-length arrays
If you need varying length arrays on a RPG with PGMINFO(*PCML) you need the *V7 option:
ctl-opt pgminfo(*PCML: *MODULE:*DCLCASE: *V7);
RPG-FAQ-020: Replace an in-use-object
We know that when we are compiling a program with REPLACE(*YES) our original object is moved to the QRPLOBJ library and running jobs doesn’t care about it.
If you need to do something similar to this process without a real source-compile you could think about QLIRNMO API, a dedicated API who move one object to a new library or name and replace the object with a given new object:
Read about QLIRNMO API here and take a look at this thread on CODE400.com
Here’s the source of the program who call QLIRNMO API
https://code400.com/forum/forum/iseries-programming-languages/free-format/1756-the-rename-object-api-qlirnmo
The API (from https://code400.com/forum/forum/iseries-programming-languages/free-format/1756-the-rename-object-api-qlirnmo)
* PROGRAM - @RENAME
* PURPOSE - rename object use API QLIRNMO
* WRITTEN -
* AUTHOR -
* PROGRAM DESCRIPTION
*--------------------------------------------------------
*
* Entry Plist
*
d @RENAME pr
d OldFile 10
d OldLib 10
d NewFile 10
d NewLib 10
d inType 10
*
d @RENAME pi
d OldFile 10
d OldLib 10
d NewFile 10
d NewLib 10
d inType 10
*
* Variable Definition
*
d Error s 34
d FromObject s 20
d ObjectType s 10
d ToObject s 20
d Replace s 1
*
* Program Info
*
d SDS
d @PGM 001 010
d @PARMS 037 039 0
d @MSGDTA 91 170
d @MSGID 171 174
d @JOB 244 253
d @USER 254 263
d @JOB# 264 269 0
//
// external calls
//
d $Rename pr extpgm('QLIRNMO')
d fromObject 20
d ObjectType 10
d ToObject 20
d Replace 1
d Error 34
/Free
//--------------------------------------------------------
// MAIN LINE
//--------------------------------------------------------
// take parms and rename --and/or-- move object
FromObject = OldFile + OldLib;
ToObject = NewFile + NewLib;
ObjectType = InType;
replace = '1';
$rename(FromObject : ObjectType : ToObject : Replace : Error);
*inlr = *on;
//--------------------------------------------------------
// *Inzsr - one time run subroutine
//--------------------------------------------------------
begsr *inzsr;
endsr;
/End-Free
---
Roberto De Pedrini
Faq400.com