This is a collection of FAQs and tips about IBM RPG Language collected from forums or IBM i related websites. We’ll try to update this post constantly with new questions, new answers, and new tips too. Feel free to use the comments area to add new tips or new questions… you are welcome!.
Index
The problem of recursive calls of RPG programs has always been a developers’ Achilles heel until the arrival of the ILE and the abandonment of the primary RPG cycle.
Basically if I want the PGMA to call the PGMB and the PGMB to call the PGMA without going into recursion I have two possible ways:
example: opt-ctl Main(MyMainProc); dcl-pr MyMainProc ExtPgm('MYPGM'); dcl-proc Main; dcl-pi -N; ... Parameters if any end-pi ... Your code. end-proc;
Insights into this MCPress Online post “RPG Fundamentals: Work with linear main programs”
Indicators in RPG no longer make sense … at least understood as indicators “IN55” or “IN(55), that is, in the numerical format of the same: they make the code cryptic for those who have not written it because they do not self-document … as a variable with its own name would do but of type “ind”.
The only thing that, in some way, keeps us tied to indicators are the attributes in DSPF Display Files or Printer Files PRTF … but even here there are tricks just to do without it.
I report below links to some interesting posts, even if old, that invite a smarter use of the indicators:
When we Debug a program or service program with the DEBUG of Rational Rdi we have the following functions of STEP:
Are they also available with the classic STRDBG?
Let’s start by saying that the difference between the STEP OVER and the STEP INTO is that the first one when it arrives on a program’s CALL or a Procedure’s call, executes the CALL or the Procedure and “stops” just after … the STEP INTO, as the word says, enters the called program or the called Procedure.
Step OVER and Step INTO also exist in STRDBG… Step Return no!
With Rational Rdi it is very convenient to debug jobs in Batch … or web services called or jobs of other users by entering a Service Entry Point SEP. Is it possible to set an Entry Point with STRDBG as with the Rational Rdi Debug?
Yes, even if it’s not so simple… this IT-Jungle post “Debugging Server Jobs In Green Screen” by Susan Gantner explains it very well:
I’ve got the same name of one file in diferent libraries … there’s a way to determine the file/library opened by my F-Spec?
Try wiht INFDS, you can get Library and File name too.
Here’s an example.
DCL-F MYFILE PRINTER(132) INFDS(OPNFBK); DCL-DS OPNFBK; ODP_TYPE CHAR(2) POS(81); // ODP Type FILE_NAME CHAR(10) POS(83); // File name LIBRARY CHAR(10) POS(93); // Library name
You can find more information and some examples of RPG code and XML-INTO at Yusi4code Blog: “XML parsing in AS400 (IBM-i) using XML-INTO“
How can I get “creation date” for an IFS Object?
There’s an IFS API stat() to retrieve some object’s attributes … but if you need the “creation date” you have to take a look at Qp0lGetAttr()–Get Attributes API: see this example at Think400 website “CBX127 Change IFS attributes – CPP”
With stat() API you can get some other interesting attributes:
D stat PR 10I 0 ExtProc('stat')
D path * Value Options(*string)
D buf
-------------
D statDS DS Qualified Template
D st_mode 10U 0
D st_ino 10U 0
D st_nlink 5U 0
D st_reserved2 5U 0
D st_uid 10U 0
D st_gid 10U 0
D st_size 10I 0
D st_atime 10I 0
D st_mtime 10I 0
D st_ctime 10I 0
D st_dev 10U 0
D st_blksize 10U 0
D st_allocsize 10U 0
D st_objtype 11A
D st_reserved3 1A
D st_codepage 5U 0
D st_ccsid 5U 0
D st_rdev 10U 0
D st_nlink32 10U 0
D st_rdev64 20U 0
D st_dev64 20U 0
D st_reserved1 36A
D st_ino_gen_id 10U 0
-----------
D fileStats DS Likeds(statDS)
if stat('/path/to/file': fileStats) < 0;
// error handling
endif;
// ccsid now in fileStats.st_ccs
How can I convert a hex character string to the decimal value in RPG as in this online service ( https://www.binaryhexconverter.com/hex-to-decimal-converter ) ?
Try ctvch() API:
**free ctl-opt dftactgrp(*no); dcl-pr cvtch extproc('cvtch'); dest pointer value; src pointer value; len int(10) value; end-pr; dcl-s hexValue char (8) inz('00BC614E'); dcl-s binValue int (10); dcl-s len int(10); len = %len(hexValue); cvtch(%addr(binValue):%addr(he xValue):len); *inlr = *on;
Or with those API strol() and itoa(): you can choose radix… not only hex (16).
ctl-opt actgrp(*new) option(*srcstmt:*nodebugio); dcl-pr strtol int(10) extproc('strtol'); iString pointer value options(*string); oBuf pointer value; iRadix int(10) value; end-pr; dcl-s pdummy pointer; dcl-pr itoa extproc('__itoa'); iNum int(10) value; oBuf pointer value; iRadix int(10) value; end-pr; dcl-s buffer char(20); dcl-s value int(10); value = strtol( '00000000000000000000000000111101':%addr(pdummy): 2); dsply value; // Shows 61 itoa( value: %addr(buffer): 16); dsply buffer; // Shows 3d *inlr = *on;
REXX can do the same
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* XCALC EXP('REVERSE("String")') */ /* ______________________________ ______________________________ _ */ /* */ /* Yet another *FREEWARE* utility from Prime Suspect Software, */ /* creating slightly above average products for the */ /* enlightened masses since 1982. */ /* ______________________________ ______________________________ _ */ /* */ /* REXX Program Name... XCALC */ /* Programmer.......... Matt Sargent */ /* Internet Address.... M.SARGENT@GENIE.GEIS.COM */ /* */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ signal on syntax parse arg string parse value space(string) with "'"expression"'" interpret 'answer =' expression answer = strip(expression) '=' answer 'SNDPGMMSG MSG(&answer)' exit syntax: syntaxerr = errortext(rc) 'SNDPGMMSG MSG(&syntaxerr)' ================ CMD PROMPT('Expression Calculator') PARM KWD(EXP) TYPE(*CHAR) LEN(256) MIN(1) + CHOICE('Character value') + PROMPT('Mathmatical expression') ========= d2x() is the REXX function to convert Decimal to heXdecimal. The data conversions available in the AS400 implementation of REXX are: b2x() binary to hex x2b() hex to binary c2d() character to decimal (EBCDIC) d2c() decimal to character (EBCDIC) c2x() character to hex (EBCDIC) x2c() hex to character (EBCDIC) d2x() decimal to hex x2d() hex to decimal
If you need to extract numeric value from a packed string:( ITJungle “Extracting Zoned and Packed Decimal Values from Character Fields“)
D usrf01 ds D TypeCode 1 2s 0 D Category 3 4p 0 D Amount 5 8p 2 -- Get the amount checking is sign select dec( dec(substr(hex(substr(usrf01,5,4)),1,5)||'.'|| substr(hex(substr(usrf01,5,4)),6,2), 7,2) * (case when substr(hex(substr(usrf01,5,4)),8,1) = 'D' then -1 else 1 end), 7,2) as Price from usrfldpf
You can crypt and decrypt a string in RPG SQL Embedded using some SQL scalar functions.
SQL cipher and decipher functions are not only for Advanced Encryption Standard (AES) algorithm, but Triple DES (TDES) and RC2 too.
Let’s take a look to this simple SQL statement: we crypt and then decrypt a string in AES with a simple password
With mytext as ( select Encrypt_AES('This is my secret', 'Pa$$w0rd') as txtEncrypted from sysibm.sysdummy1) select Decrypt_char(txtEncrypted, 'Pa$$w0rd') from mytext;
In this example, we cipher a string in RPG with SQL Embedded … pay attention to the Encrypted variable length, the cipher algorithm generally give out a long string. Using a constant as a password string is not a good idea, store it in a table or in the ENCRYPTION PASSWORD special register.
DCL-S Text VarChar(20); DCL-S Encrypted VarChar(256); DCL-S Password VarChar(15) inz('yourPassWord') Text = 'Whatever Text' Exec SQL Set :Encrypted = Encrypt_AES(Text, PassWord);
If you don’t like SQL and you want to get hurt wit system’s API you can see at:
Encrypt Data (QC3ENCDT, Qc3EncryptData) API
References:
If you need some examples and howtos about system’s API in RPG there is a great website by Carsten Flesburg:
--- Roberto De Pedrini Faq400.comWith a little trick even a simple SELECT statement can execute any system command! Let's see how to do that...
A mini-serial guide to configuring, managing, using, and troubleshooting the IBM i NetServer
A mini-serial guide to configuring, managing, using, and troubleshooting the IBM i NetServer
A mini-serial guide to configuring, managing, using, and troubleshooting the IBM i NetServer
A mini-serial guide to configuring, managing, using, and troubleshooting the IBM i NetServer
A mini-serial guide to configuring, managing, using, and troubleshooting the IBM i NetServer