IBMi (AS400) fans only ' Program Status Data Structure (PSDS), %editc BIF (Built-In Function), and %subst BIF in RPG free.

Rpg free example

The program is indeed a simple and minimal example that demonstrates the usage of Program Status Data Structure (PSDS), %editc BIF (Built-In Function), and %subst BIF 
(Built-In Function) in RPG free.


Program Status Data Structure (PSDS): The psds named Pgm is utilized to store system-related information like the current user and program time. The pgm.User and pgm.PgmTime fields are accessed within the program.


%editc BIF: The %editc BIF is used to convert the zoned decimal value P_PGMTIME into a character representation. This is commonly done when formatting numeric values for display.


%subst BIF: The %subst BIF is used to extract portions of the formatted time string P_PGMTIMEchar. It is used to create a time string in the format "HH:MM:SS" by extracting and concatenating substrings.


Overall, this program is a concise example that showcases the use of these RPG features for obtaining system-related information and manipulating data for display.

RPG's Program Data Structure.

in RPG (Report Program Generator), the Program Data Structure (also known as PDS or Program Status Data Structure) is a special data structure used to control the flow and status of the program. It includes information about indicators, error conditions, and the program's overall status.

The Program Data Structure is typically defined at the beginning of an RPG program and is used to manage the program's execution. It consists of various fields, each serving a specific purpose.

Here is a basic example :

  ctl-opt option(*nodebugio:*srcstmt:*nounref);

  dcl-ds Pgm psds qualified ;
    User    char(10) pos(358); // 358 367 Current user
    PgmTime zoned(6) pos(282); // 282 287 Program Time
  end-ds ;

  dcl-s P_USER char(10);
  dcl-s P_PGMTIME zoned(6);
  dcl-s P_PGMTIMEchar char(52);

// *******************************************************
// * PGM start                                           *
// *******************************************************

  P_USER    = pgm.User;
  P_PGMTIME = pgm.PgmTime;
  P_PGMTIMEchar = %subst(%editc(P_PGMTIME:'X'):1:2) + ':' +
                  %subst(%editc(P_PGMTIME:'X'):3:2) + ':' +

  Dsply P_USER;
  Dsply P_PGMTIMEchar;

  *inlr = *on; 

This RPG program performs the following actions:

Control Options:

The ctl-opt statement is used to set various control options for the program.

option(*nodebugio) indicates that debug I/O operations are not allowed.

option(*srcstmt) allows the use of the SRCSTMT keyword in debugging.

option(*nounref) specifies that unreferenced data structures are not considered as errors.

Program Data Structure (PDS):

A Program Data Structure (psds) named Pgm is declared.

It is qualified (qualified) to indicate that its subfields are referenced using dot notation.

It contains two subfields:

User: A character field of length 10, located at position 358 in the program status data structure (PSDS). This field represents the current user.

PgmTime: A zoned decimal field of length 6, located at position 282 in the PSDS. This field represents the program time.

Local Variables:

P_USER: A local character variable of length 10 is declared to store the value of pgm.User.

P_PGMTIME: A local zoned decimal variable of length 6 is declared to store the value of pgm.PgmTime.

P_PGMTIMEchar: A local character variable of length 52 is declared to store the formatted version of the program time.

Main Procedure:

Values from the PSDS (pgm.User and pgm.PgmTime) are assigned to the local variables P_USER and P_PGMTIME.

P_PGMTIMEchar is then calculated by formatting P_PGMTIME into a string with the format "HH:MM:SS".

The Dsply operation is used to display the values of P_USER and P_PGMTIMEchar on the screen.

Finally, *inlr is set to *on to indicate that the program should end when it reaches the last record.

In summary, the program retrieves the current user and program time from the program status data structure (PSDS), formats the program time, and displays both the user and the formatted time on the screen using the Dsply operation. After that, the program ends (*inlr = *on).


  1. Hi Aldo, for User and date/time variables you don't need PSDS, you can use: "Specifying INZ(*USER) intializes any character field or subfield to the name of the current user profile. Character fields must be at least 10 characters long. If the field is longer than 10 characters, the user name is left-justified in the field with blanks in the remainder.

    Date fields can be initialized to *SYS or *JOB. Time and Timestamp fields can be initialized to *SYS." taken from RPG manual

    1. Thank you for your valuable input! It's fantastic to learn alternative approaches, and your contribution adds depth to the discussion. Grazie mille for sharing your knowledge!

  2. In the case of a job that swaps the current profile and ends with *InLR=*Off, may need to retrieve in a sub-proc.
    dcl-s currentUser char(10) inz(*user);

    1. Thank you so much for your insightful observation! Your comment adds valuable considerations to the discussion.
      I appreciate your engagement and hope to hear more from you in the future. Grazie mille!


Post a Comment

Popular posts from this blog

IBMi (AS400) fans only ‘ Memories (IBM Coding Forms)

IBM i (AS400) fans only ' How to read a TXT file in the IFS with SQL