Midrange News for the IBM i Community

Posted by: Bob Cozzi
Rogue Programmer
Cozzi Productions, Inc.
IBM i API Prototypes in RPG IV
© 1996-2015 by Bob Cozzi has no ratings.
Published: 28 Jul 2015
Revised: 24 Jan 2020 - 1544 days ago
Last viewed on: 15 Apr 2024 (11786 views) 

Using IBM i? Need to create Excel, CSV, HTML, JSON, PDF, SPOOL reports? Learn more about the fastest and least expensive tool for the job: SQL iQuery.

IBM i API Prototypes in RPG IV Published by: Bob Cozzi on 28 Jul 2015 view comments
© 1996-2015 by Bob Cozzi

Bob Cozzi's Prototypes for RPG IV Programmers

This is an on-going list of Prototypes I've been using for years. Feel free to cut/paste them into your own code. Be sure to check back occasionally for updates and additions. Or Click the FOLLOW icon in the left margin to receive an email when I make changes to this page. If there's an API you'd like to have me include (I've prototyped most of them) feel free to leave a comments below and I'll see what I can do.

NOTE: If you're representing one of the myriad websites that just cut/pastes code and republishes without credit to the author. Please click here.


QCMDEXC - Run a Command

     D QCMDEXC         PR                  extPgm('QCMDEXC')
           // command string
     D  cmdStr                    32702A   Const OPTIONS(*VARSIZE)
           // command string length
     D  cmdLen                       15P 5 Const
          // double-byte support (value='IGC' or don't specify)
     D  dbcsFlag                      3A   Const OPTIONS(*NOPASS)

The QCMDEXCs API is the oldest on the system and one that is almost always incorrectly prototyped.

system - C-version of Run a Command

    D system_MSGID    S              7A   Import('_EXCP_MSGID')

    D system          PR            10I 0 extProc('system')
    D  szCmd                          *   Value OPTIONS(*STRING:*TRIM) 

Unlike the QCMDEXC API, the system API does not require a length parameter. It also doesn't respond the same way QCMDEXC does when errors occur. instead of receiving messages, you check the return value. If it is equal to 1, then an error occured. You can check the optional imported field named _EXCP_MSGID. It will contain the exception/error message ID.

sleep - Delays the job for the given number of seconds.

    D sleep           PR            10U 0 extProc(*CWIDEN:'sleep')
    D   seconds                     10U 0 value 

So many programmers continue to use luddite-style DO loops when this feature has been available to RPGIV for over 20 years.

cvthc - Convert to Hex

      **  The CVTHC MI (convert to hex) instruction
      **      'F1F2F3' <-- '123'
     D toHex           PR                  extProc(*CWIDEN:'cvthc')
     D  szHexVal                  65534A   OPTIONS(*VARSIZE)
     D  szCharVal                 32766A   CONST OPTIONS(*VARSIZE)
     D  hexLen                       10I 0 Value

The cvthc MI instruction converts 1 character to 2 hexadecimal values. It can perform this task on as many characters as necessary, at once. The 64k limit on the above prototype isn't real. You can actually pass in up to 16 megabytes of data. So if you're running IBM i v7.1 or later, you can use the LEN keyword for the length of the parameters instead of the legacy columnar lengths.

Note: the length (3rd) parameter is always the number of hexadecimal characters. To put it simply, if converting a 10 normal character value to 20 hexadecimal characters, the length is 20. This is the same for both cvthc and cvtch.

cvtch - Convert from Hex

      **  The CVTCH MI (convert from hex) instruction
      **      '123' <-- 'F1F2F3'
     D fromHex         PR                  extProc(*CWIDEN:'cvtch')
     D  szCharVal                 32766A   OPTIONS(*VARSIZE)
     D  szHexVal                  65535A   CONST OPTIONS(*VARSIZE)
     D  hexLen                        10I 0 Value

The cvtch MI instruction converst 2 hexadecimal symbols of 0 to 9 and A to F into 1 character. See the cvthc prototype for more information.

memicmp - Compare two variables and ignore upper/lower case differences

     D memicmp         PR            10I 0 extProc(*CWIDEN:'__memicmp')
     D  pVal1                     32767A   Const OPTIONS(*VARSIZE)
     D  pVal2                     32767A   Const OPTIONS(*VARSIZE)
     D  nBufLen                      10U 0 Value

The memicmp API allows you to compare two character strings for equality. If the variables are equal, the API returns 0. Otherwise they are not equal. The comparison is case insensitive.

QUSCMDLN - Popup IBM I CL Command Line Window

      D QUSCMDLN        PR                  extPgm('QUSCMDLN')

This API pops up a small command line window similar to what you see in tools such as SEU, the Debugger, and the SQL Query File interactive viewer. Type any command and press Enter to run. The API is cursor sensitive so it will avoid the area of the screen containing the cursor.

QsnRtvMod - Retrieve Current Display Mode (*DS3 or *DS4)

     D QsnRtvMod       PR             1A   extProc('QsnRtvMod')
     D  curMode                       1A   OPTIONS(*OMIT)
     D  dsmLLEnv                     10I 0 OPTIONS(*OMIT)
     D  apiError                     16A   OPTIONS(*OMIT:*VARSIZE)

Use this API to retrieve the current display mode. '3'=Normal, '4'=Wide mode. Basically '3' = 24x80 and '4' = 27x132

No parameters are necessary to use this API, however you MUST pass *OMIT on each of the 3 parameters.

For example:

        if (qsnRtvMod(*OMIT : *OMIT : *OMIT) = '4');  // *DS4 mode? 
           // do something interesting.



CEE APIs are so called "built-in" functions. That is their code is embedded right inside your program. Think of them as unrefined Built-in Functions. They work just like an IBM RPG IV built-in function, but don't have the clean packaging around them. Two that I use a lot and have for about 20 years are CEEDAYS and CEEDATE.

CEEDAYS - Convert Date to Lillian Date Format

     D CEEDAYS         PR                  extProc('CEEDAYS')
     D                                     OPDESC
     D  inDate                      255A   Const OPTIONS(*VARSIZE)
     D  inFormat                    255A   Const OPTIONS(*VARSIZE)
     D  nDays                        10I 0
     D  apiError                     12A   OPTIONS(*OMIT)

The CEEDAYS API isn't quite as useful in RPG IV as it is in C/C++ or CL. This API accepts a date varaible (as a character string) and calculates its internal "lilian" date. A "lilian date" is a date represented as the number of days since 14 October 1582. To do this calculation in RPG IV natively, you'd need to hardcode that 1582 date somewhere. CEEDAYS does not need that date--it is built-in.

CEEDATE - Convert Lilian Date to User-Formatted Date String

     D CEEDATE         PR                  extProc('CEEDATE')
     D                                     OPDESC
     D  inDays                       10I 0
     D  outFormat                   255A   Const OPTIONS(*VARSIZE)
     D  outDate                     255A   OPTIONS(*VARSIZE)
     D  apiErrorDS                   12A   OPTIONS(*OMIT)

Once a "number of days since 14 October 1582" is calculated whether using good old RPG IV %DIFF or the CEEDAYS API, you can then turn that simple number into something users can read using CEEDATE. Specify the lilian date as parm 1, a text value (character variable, named constant, or literl) as Parm 2 that indicates what format you'd like your date; and a character variable to receive the date as text for parm 3 and always pass *OMIT as parm 4.

Return to midrangenews.com home page.
Sort Ascend | Descend