Saturday, 12 October 2024

Basic CL Commands in IBM i (AS400)

When writing a Control Language Program (CLP) on IBM i (AS400), various CL commands are embedded within the program to interact with the system, manage processes, and communicate with users. Unlike some external commands like CRTCLPGM used for compiling programs, the commands used within a CLP program are designed to perform specific tasks during execution. In this article, we will cover essential commands typically used inside CLP programs, focusing on their purpose and practical usage in program flow.

Here are the basic CL commands we'll explore:

  1. WRKOBJ (Work with Objects)
  2. RUNSQLSTM (Run SQL Statements)
  3. SNDPGMMSG (Send Program Message)
  4. SNDMSG (Send Message)
  5. MONMSG (Monitor Message)

1. WRKOBJ (Work with Objects)

WRKOBJ is primarily an interactive command but can also be useful within CL programs when combined with object-checking commands such as CHKOBJ or DSPOBJD to verify the existence or state of system objects like files, programs, and libraries.

Usage in CLP Program

In CLP programs, you generally use commands like CHKOBJ to verify the existence of objects (which might be part of a pre-check step in your CLP), but you can use WRKOBJ outside of program control. Here's how CHKOBJ could work in place of WRKOBJ in a CLP program:

Syntax: CHKOBJ

CHKOBJ OBJ(LIBRARY/OBJECT) OBJTYPE(*FILE)

Example in CLP:

PGM /* Check if the object exists */ CHKOBJ OBJ(MYLIB/MYFILE) OBJTYPE(*FILE) MONMSG MSGID(CPF9801) EXEC(DO) /* If file does not exist, send a message and terminate */ SNDPGMMSG MSG('File MYFILE not found in MYLIB') TOPGMQ(*EXT) RETURN ENDDO /* If object exists, continue with further operations */ SNDPGMMSG MSG('Object found, proceeding') TOPGMQ(*EXT) /* Continue program logic */ ENDPGM

This example demonstrates how to check whether a file (MYFILE) exists in a specific library. If it doesn't, the program sends a message and stops further execution using the RETURN command. This is a basic and essential technique when working with objects within CLP programs.


2. RUNSQLSTM (Run SQL Statements)

The RUNSQLSTM command is used to execute SQL statements stored in a source member. SQL provides powerful capabilities for interacting with the database, and when you need to incorporate database manipulations within a CLP program, SQL statements can be called using RUNSQLSTM.

Syntax

RUNSQLSTM SRCFILE(LIBRARY/SOURCEFILE) SRCMBR(SOURCEMEMBER)

Example in CLP:

Let’s assume you need to update a database file in the middle of a CLP program. You could store the SQL command in a source member and call it from the CLP:

PGM /* Pre-checks and other logic */ /* Run an SQL statement to update records */ RUNSQLSTM SRCFILE(MYLIB/QSQLSRC) SRCMBR(UPDREC) SNDPGMMSG MSG('SQL statement executed successfully') TOPGMQ(*EXT) /* Further program logic */ ENDPGM

In this example, the SQL statement is stored in the source member UPDREC in the source physical file QSQLSRC. This technique is especially useful when working with complex SQL operations such as updates, inserts, or creating database objects directly from within a CLP program.


3. SNDPGMMSG (Send Program Message)

SNDPGMMSG is one of the most important commands used in CLP programs. It allows you to send messages to the external message queue or job log, which is crucial for informing users or operators about the status of the program. It replaces the deprecated DSPLY statement.

Syntax

SNDPGMMSG MSG('message text') TOPGMQ(*EXT)

Example in CLP:

PGM DCL VAR(&USERID) TYPE(*CHAR) LEN(10) /* Retrieve the current user profile */ RTVJOBA USER(&USERID) /* Send a message to the job log */ SNDPGMMSG MSG('Hello ' *CAT &USERID *TCAT ', Welcome!') TOPGMQ(*EXT) /* Continue with program execution */ ENDPGM

In this example, the program retrieves the current user profile using the RTVJOBA command and then sends a personalized message to the message queue using SNDPGMMSG. This is a practical way to send feedback to the user during execution.


4. SNDMSG (Send Message)

The SNDMSG command is used to send messages to other users or system operators. While SNDPGMMSG sends messages to the job log or message queue, SNDMSG communicates directly with users on the system, making it ideal for sending notifications.

Syntax

SNDMSG MSG('message text') TOUSR(user or group)

Example in CLP:

PGM /* Backup completed, notify the system administrator */ SNDMSG MSG('Backup process for MYLIB completed successfully.') TOUSR(SYSADMIN) /* Continue with further operations */ ENDPGM

In this example, once a task (such as a backup) is completed, the program sends a notification to the system administrator (SYSADMIN). This is a common pattern in CLP programs that handle system maintenance or batch processing.


5. MONMSG (Monitor Message)

MONMSG is used to monitor for specific errors or exceptions that occur during the execution of a command in a CLP program. When a monitored condition occurs (e.g., a missing object or failed operation), the program can handle the error gracefully by performing alternative actions, logging the error, or even terminating the process.

Syntax

MONMSG MSGID(message ID) EXEC(command or block of commands)

Example in CLP:

PGM /* Try to perform an operation */ DLTF FILE(MYLIB/MYFILE) MONMSG MSGID(CPF2105) EXEC(DO) /* If file not found, send a message */ SNDPGMMSG MSG('File not found, cannot delete') TOPGMQ(*EXT) ENDDO /* Continue with further operations */ ENDPGM

In this example, the program attempts to delete a file (DLTF), and if the file is not found (message ID CPF2105), the program handles the error by sending a message to the external message queue using SNDPGMMSG. MONMSG is critical in CLP programs to ensure smooth error handling.


Practical Example: Combining Commands in a CLP Program

Let’s now combine all these commands into a single, simple CLP program. This program checks for an object, runs an SQL statement, handles errors, and sends appropriate messages to both the job log and users.

PGM DCL VAR(&OBJEXISTS) TYPE(*CHAR) LEN(10) /* Check if the object exists */ CHKOBJ OBJ(MYLIB/MYFILE) OBJTYPE(*FILE) MONMSG MSGID(CPF9801) EXEC(DO) /* Object not found, send message */ SNDPGMMSG MSG('File MYFILE not found') TOPGMQ(*EXT) RETURN ENDDO /* If object exists, run SQL statement */ RUNSQLSTM SRCFILE(MYLIB/QSQLSRC) SRCMBR(UPDREC) MONMSG MSGID(SQLxxxx) EXEC(DO) /* Handle SQL errors */ SNDPGMMSG MSG('SQL execution failed') TOPGMQ(*EXT) RETURN ENDDO /* Notify user of successful completion */ SNDMSG MSG('MYLIB processing complete') TOUSR(SYSADMIN) ENDPGM

Explanation:

  • CHKOBJ checks whether the file MYFILE exists in the library MYLIB.
  • RUNSQLSTM executes an SQL statement stored in the source member UPDREC.
  • MONMSG captures any errors from the commands, sending appropriate messages.
  • SNDPGMMSG sends feedback to the job log, and SNDMSG notifies the system administrator when the process is completed.

Conclusion

The commands discussed—CHKOBJ, RUNSQLSTM, SNDPGMMSG, SNDMSG, and MONMSG—are fundamental to CL programming within IBM i. These commands allow for robust error handling, database manipulation, and user communication, all within a CLP program. Mastering these basic commands will enable you to write effective, efficient, and error-tolerant CL programs that interact with the system and users in meaningful ways.

In the next article, we will explore more advanced commands and techniques to expand your CL programming toolkit. Stay tuned!

Creating Your First CL Program on IBM i (AS400)

 A CL program is a series of IBM i commands that automate tasks, manage system operations, and handle user interactions. CL programs can call other programs, submit jobs, process files, and display messages, among many other things. Unlike general-purpose programming languages like Java or Python, CL is primarily focused on interacting with the IBM i operating system to control system-level operations.


Steps to Create Your First CL Program

To build your first CL program, we will follow these steps:

  1. Create a Source File and Member: The file will store your CL program.
  2. Write the CL Program: Learn the basic structure and commands.
  3. Compile the CL Program: Convert the source code into a runnable object.
  4. Run the CL Program: Execute the compiled program to see it in action.

Step 1: Create a Source File and Member

Before you start writing your CL program, you need to create a source member within a source physical file. The source file is where your program's source code is stored, and each program resides as a separate member in that file.

Option 1: Using SEU (Source Entry Utility) and PDM (Program Development Manager)

  1. Log in to your IBM i system via a terminal emulator (e.g., IBM i Access Client Solutions or TN5250J).

  2. Create a source physical file if one does not exist already. For CL programs, the common source file name is QCLSRC:

    CRTSRCPF FILE(LIBRARY/QCLSRC) RCDLEN(112)
  3. Once the source file is created, start PDM to create a new source member:

    STRPDM
  4. Select Option 3 (Work with members) and specify the QCLSRC file and the library where it resides.

  5. Create a new member by typing 2=Create next to an empty line, and give the member a name (e.g., MYCLPGM), with the source type CLP.

Option 2: Using Visual Studio Code with the "Code for i" Plugin

  1. Open Visual Studio Code with the Code for i plugin installed.
  2. Connect to your IBM i system by configuring the host, username, and password.
  3. Navigate to the library and source file (e.g., QCLSRC) within the Remote Explorer.
  4. Right-click and create a new member for your CL program.

Option 3: Using RDi (Rational Developer for i)

  1. Launch Rational Developer for i (RDi).
  2. Navigate to the Remote Systems Explorer (RSE).
  3. Right-click on the QCLSRC source file and select New > Member.
  4. Name the source member and set the type to CLP.

Step 2: Writing the CL Program

Every CL program follows a basic structure that begins with PGM and ends with ENDPGM. The PGM command defines the start of the program, while ENDPGM signifies its end.

Basic CL Program Structure

PGM /* Your program logic goes here */ ENDPGM

Example: A Simple "Hello, World" Program

We will create a program that sends a message to the user. Since the DSPLY statement cannot be used in CL, we will use the correct command SNDPGMMSG (Send Program Message) to display a message.

Here is how your first program might look:

PGM SNDPGMMSG MSG('Hello, World!') ENDPGM

Let’s break this down:

  • PGM: Marks the start of the program.
  • SNDPGMMSG MSG('Hello, World!'): Sends the message "Hello, World!" to the user.
  • ENDPGM: Marks the end of the program.

Writing Your Program

  • If you are using SEU, navigate to the source member you created, and enter the CL program directly in the editor.
  • If you are using RDi or VS Code, open the newly created member and start typing your CL code there. These modern tools will assist you with syntax highlighting and error detection.

Step 3: Compiling the CL Program

Once you’ve written your program, the next step is to compile it. Compiling translates your source code into an executable object that can run on the IBM i system.

The CRTCLPGM command is used to compile a CL program. Here’s how to compile your program, depending on your tool:

Option 1: Using SEU/PDM

  1. Exit SEU after saving your program.

  2. On the IBM i command line, enter the following command:

    CRTCLPGM PGM(LIBRARY/PROGRAM_NAME) SRCFILE(LIBRARY/QCLSRC)

    Replace LIBRARY with the name of the library where your source resides and PROGRAM_NAME with the name of the source member you created.

  3. Press Enter to compile. If there are no syntax errors, the program will be compiled and available to run.

Option 2: Using Visual Studio Code with Code for i

  1. Right-click on the source member in VS Code.
  2. Select Compile from the options. The Code for i plugin will automatically run the CRTCLPGM command for you.

Option 3: Using RDi

  1. Right-click on the source member and select Compile.
  2. RDi will run the CRTCLPGM command and display any errors or warnings in the Problems view.

Step 4: Running the CL Program

Now that your program is compiled, it’s time to run it.

Option 1: Running from the Command Line

To run your program directly from the IBM i command line, use the CALL command:

CALL PGM(LIBRARY/PROGRAM_NAME)

This will execute the program, and you should see the message "Hello, World!" displayed on the screen.

Option 2: Running from a Modern IDE (RDi or VS Code)

  • RDi: You can submit the program to run directly from the IDE by right-clicking on the source member and selecting Run.
  • VS Code: Use the Remote Command feature in the Code for i plugin to run your CL program remotely.

Verifying the Output

If your program executes successfully, the system will send the message "Hello, World!" to the job's message queue. You can view this message by checking the Message Queue of your job. For example:

  • From the command line, type:

    DSPJOBLOG

    This will display the job log where you can see the message sent by your program.


Debugging and Troubleshooting

If your program fails to compile or does not behave as expected, here are a few common issues and tips to resolve them:

  1. Syntax Errors: If the program doesn’t compile, the system will provide a detailed error message. Double-check your code for typos or missing commands.
  2. Program Not Found: If you try to run the program and receive an error stating "Program not found," ensure that the program was compiled correctly and that the PGM parameter in the CALL command matches the correct library and program name.
  3. Checking Messages: If the program runs but the output doesn’t appear, check the message queue using the DSPJOBLOG command to see if the message was successfully sent.

Conclusion

Congratulations! You’ve created, compiled, and run your first CL program on IBM i. This simple "Hello, World!" program has introduced you to the basic structure and steps involved in CL programming.

In this article, you’ve learned how to:

  • Create a source file and member to store your program.
  • Write a basic CL program using the correct command (SNDPGMMSG).
  • Compile the program using the CRTCLPGM command.
  • Run the program using the CALL command and check for output.

In the next article, we’ll dive deeper into the topic of Data Types and Variables in CL Programming, where you’ll learn how to manage and manipulate data within your programs. Stay tuned!

Setting Up Your Development Environment for CL Programming on IBM i

In this article, we will explore how to set up your development environment to begin working with Control Language Programming (CLP) on IBM i (formerly AS400). Setting up the right environment is essential for writing, testing, and running your CL programs efficiently. We’ll cover both legacy and modern tools, including SEU, RDi, Access Client Solutions, and the Visual Studio Code plugin “Code for i.”


Understanding the IBM i Development Ecosystem

IBM i is a robust and integrated platform with various tools for development, including legacy text-based tools like SEU, modern Integrated Development Environments (IDEs) like RDi, and even options for using popular editors like Visual Studio Code. Below are the main development tools available for CL programming on IBM i:

  1. Source Entry Utility (SEU): The traditional editor for writing CL programs.
  2. Program Development Manager (PDM): Utility for managing source members and libraries.
  3. Rational Developer for i (RDi): IBM's modern, Eclipse-based IDE for IBM i development.
  4. Visual Studio Code (VS Code): A popular code editor with the Code for i plugin, offering a modern interface for IBM i programming.
  5. Access Client Solutions (ACS): A GUI tool to access IBM i system functions.
  6. 5250 Terminal Emulation: A terminal interface for direct interaction with the system.

We’ll now discuss how to set up your environment using these tools.


Option 1: Setting Up with SEU and PDM (Legacy Tools)

Though SEU and PDM are considered legacy tools, they remain widely used for CL programming on IBM i. If you are working in an environment that still uses these tools, here’s how to get started.

Step 1: Logging into IBM i

You’ll need to log into the IBM i system using a terminal emulator:

  • IBM i Access Client Solutions (ACS): Provides a 5250 terminal emulator.
  • TN5250J: An open-source terminal emulator for accessing IBM i.

Step 2: Using PDM to Manage Source Members

To develop a CL program, first create a source member in a source physical file. PDM is used for managing these files.

  1. Enter STRPDM on the IBM i command line to start PDM:

    STRPDM
  2. In PDM, select Option 3 to work with source file members and create a new member in a source physical file like QCLSRC.

Step 3: Writing CL Programs with SEU

To write CL programs, use SEU. Once you’ve created the source member in PDM, type 2=Edit next to the member name to open SEU. This line-based editor allows you to input your CL code.

Here’s an example CL program using the correct statement to send a message:

PGM SNDPGMMSG MSG('Hello, World!') ENDPGM

Step 4: Compiling the CL Program

After writing your CL code, compile it with the CRTCLPGM command:

CRTCLPGM PGM(LIBRARY/PROGRAM_NAME) SRCFILE(LIBRARY/QCLSRC)

Option 2: Setting Up with Rational Developer for i (RDi)

Rational Developer for i (RDi) is IBM’s Eclipse-based IDE, offering a modern interface with code assistance, debugging, and more.

Step 1: Installing and Configuring RDi

Download and install RDi from IBM’s website. Once installed, configure your connection to IBM i through Remote Systems Explorer (RSE). After connecting, you can manage source files, members, and libraries through the IDE.

Step 2: Writing CL Programs in RDi

Once connected, create a new source member and write your CL programs using RDi’s powerful editor. Syntax highlighting and code suggestions make development easier.

For example:

PGM SNDPGMMSG MSG('Hello, World!') ENDPGM

Step 3: Compiling and Running the CL Program in RDi

RDi allows you to compile directly from the IDE. Right-click on the source member and select Compile to run the CRTCLPGM command and compile your program.


Option 3: Using Visual Studio Code with the "Code for i" Plugin

For those who prefer Visual Studio Code (VS Code), the Code for i plugin enables development on IBM i. This modern editor offers a lightweight and highly customizable environment.

Step 1: Installing Visual Studio Code and Code for i Plugin

  1. Download and install VS Code.
  2. Install the Code for i plugin from the VS Code extensions marketplace.

Step 2: Connecting to IBM i

Once the plugin is installed, configure the connection to your IBM i system by entering your system's hostname and credentials. This plugin allows you to browse libraries, edit source members, and compile programs directly within VS Code.

Step 3: Writing CL Programs in VS Code

Using the Code for i plugin, you can create and edit CL programs just like in RDi. Here’s an example CL program written in VS Code:

PGM SNDPGMMSG MSG('Hello, World!') ENDPGM

VS Code provides syntax highlighting and code completion for CL, making it a versatile tool for IBM i development.

Step 4: Compiling and Running CL Programs in VS Code

You can compile your CL programs directly from VS Code by using the built-in commands from the Code for i plugin, which automatically invokes the appropriate IBM i commands.


Option 4: Using IBM i Access Client Solutions (ACS)

IBM i Access Client Solutions (ACS) provides access to IBM i systems, including a 5250 terminal emulator and system management tools. You can also edit source members using ACS’s built-in editor.

Step 1: Installing and Configuring ACS

  1. Download IBM i Access Client Solutions from IBM’s website.
  2. Install ACS on your local machine and configure the connection to your IBM i system.

Step 2: Writing CL Programs in ACS

You can create and edit source members using either the terminal emulator or ACS’s Source Editor, which provides syntax highlighting.


Conclusion

Setting up your CL development environment on IBM i can be done using a variety of tools, from legacy options like SEU and PDM to modern IDEs such as RDi and even Visual Studio Code with the Code for i plugin. Each tool offers different strengths, allowing you to pick the one that best suits your workflow.

With this setup, you are ready to start writing, editing, and compiling CL programs. In our next article, we’ll take a deeper dive into Data Types and Variables in CL programming, covering how to manage and manipulate data effectively in your programs. Stay tuned!

Friday, 11 October 2024

CLP Syntax and Structure Overview

In this article, we will explore the fundamental syntax and structure of CLP (Control Language Programming) on IBM i (formerly AS400). Understanding the syntax is critical to writing CL programs that automate tasks, manage jobs, and interact with the system. This guide will walk you through the essential elements of CLP, including the structure of a CL program, the rules of syntax, and the core components you’ll use when writing your own CL programs.


Basic Structure of a CL Program

A CL program is a sequence of commands executed by the IBM i operating system to perform specific tasks. These tasks can range from managing files and data to submitting jobs and sending messages.

Here’s a simple overview of a CL program structure:

PGM /* Start of the program */ /* Declarations and initializations */ /* CL commands */ ENDPGM /* End of the program */

The two most important parts of every CL program are:

  • PGM: Marks the beginning of the program.
  • ENDPGM: Marks the end of the program.

Between these two statements, you will place your CL commands, variable declarations, and logic flow.


Key Components of CLP Syntax

  1. Commands: CL programs are driven by commands, which perform specific actions. Commands like SNDPGMMSG (Display), SNDMSG (Send Message), and SBMJOB (Submit Job) are the building blocks of a CL program.

    For example, here’s a simple command that displays a message on the screen:

    SNDPGMMSG MSG('Hello World!')
  2. Parameters: Many commands take one or more parameters that provide additional instructions. Parameters follow the command and are separated by spaces.

    For example, in the DSPLY command, the message 'Hello, World!' is the parameter being passed to the DSPLY command:

    SNDPGMMSG MSG('Hello World!')

    Some commands may have multiple parameters, which are often separated by commas:

    SNDMSG MSG('Processing completed') TOUSR(USER1)
  3. Variables: Variables are used in CL programs to store data for later use, such as user inputs, system values, or intermediate results.

    You can declare variables using the DCL (Declare) command. Variables can hold different types of data, including characters, numbers, and dates.

    Here’s an example of declaring a character variable:

    DCL VAR(&USERNAME) TYPE(*CHAR) LEN(10)
  4. Comments: Comments in CL programs are indicated by double slashes /* ... */. They can be placed on any line to describe what the program is doing. Comments are ignored by the system but are useful for developers to understand the code.

    Here’s an example of a comment:

    SNDPGMMSG MSG('Starting the program') /* Display start message */

CLP Command Syntax

Let’s break down the structure of a CL command. Each CL command generally follows this pattern:

COMMAND_NAME [parameters]
  • COMMAND_NAME: The name of the command (e.g., DSPLY, CRTCLPGM, SBMJOB).
  • parameters: The values or options passed to the command to define its behavior.

Commands in CL programs are written one per line, and their parameters can include strings, variables, or other system values.

Example 1: The SNMSGPGM Command

The DSPLY command is used to display a message on the screen. Here’s the basic syntax:

SNGMSGPGM MSG('Your message here')
  • message: This parameter is the text you want to display.

Example:

SNDMSGPGM MSG('Hello, welcome to the system!')

This will display the message: "Hello, welcome to the system!".

Example 2: The SBMJOB Command

The SBMJOB command is used to submit a job to the job queue for batch processing. This command can have several parameters to define the job name, user, job queue, etc.

SBMJOB CMD(CALL PGM(MYPROGRAM)) JOB(MYJOB) JOBQ(QBATCH)

In this example:

  • CMD(CALL PGM(MYPROGRAM)): Submits the job to call a program named MYPROGRAM.
  • JOB(MYJOB): Names the job MYJOB.
  • JOBQ(QBATCH): Specifies that the job should be submitted to the QBATCH job queue.

Declaring and Using Variables

Variables are crucial for holding values that can change during program execution. The DCL (Declare) command is used to declare variables in CL programs. Variables are typically named with an & symbol (e.g., &USERNAME, &RESULT).

Syntax for Declaring a Variable:

DCL VAR(&variable-name) TYPE(type) LEN(length)
  • VAR(&variable-name): The name of the variable.
  • TYPE(type): The data type, which can be:
    • *CHAR: Character string.
    • *DEC: Decimal number.
    • *LGL: Logical (true/false).
    • *INT: Integer number.
  • LEN(length): The length of the variable (relevant for character and decimal types).

Example:

DCL VAR(&USERNAME) TYPE(*CHAR) LEN(10) DCL VAR(&COUNTER) TYPE(*DEC) LEN(3 0)

In this example:

  • &USERNAME is a character variable with a length of 10.
  • &COUNTER is a decimal variable that can store values up to 999.

Assigning Values to Variables

You can assign values to variables using the CHGVAR (Change Variable) command.

CHGVAR VAR(&USERNAME) VALUE('JohnDoe') CHGVAR VAR(&COUNTER) VALUE(5)
  • CHGVAR VAR(&USERNAME) VALUE('JohnDoe'): Assigns the value 'JohnDoe' to the &USERNAME variable.
  • CHGVAR VAR(&COUNTER) VALUE(5): Sets the &COUNTER variable to 5.

Conditional Statements and Control Flow

In CL programs, you can control the flow of execution using conditional statements and loops. These are important for implementing logic in your programs.

IF Statement

The IF statement allows you to execute commands based on a condition.

IF COND(&COUNTER *EQ 5) THEN(SNDMSGPGM MSG('Counter is 5'))
  • COND(&COUNTER *EQ 5): The condition being evaluated (if &COUNTER equals 5).
  • THEN(SNDMSGPGM MSG('Counter is 5')): The command to execute if the condition is true.

DO and ENDDO Blocks

The DO block allows you to group multiple commands that should be executed together if a condition is met. The block ends with ENDDO.

IF COND(&COUNTER *LT 10) THEN(DO) CHGVAR VAR(&COUNTER) VALUE(&COUNTER + 1) SNDMSGPGM MSG('Counter incremented') ENDDO

In this example, if &COUNTER is less than 10, the program will increment the counter and display a message.


Handling Loops in CLP

CL programs support looping structures to repeatedly execute commands. Two common types of loops are DOWHILE and FOR.

DOWHILE Loop

A DOWHILE loop continues executing a block of commands as long as a condition remains true.

DOWHILE COND(&COUNTER *LT 5) CHGVAR VAR(&COUNTER) VALUE(&COUNTER + 1) SNGMSGPGM MSG('Loop iteration') ENDDO

This loop will continue until &COUNTER reaches 5.

FOR Loop

The FOR loop is another method of controlling repetitive execution, commonly used when you know the number of iterations.

FOR VAR(&I) FROM(1) TO(10) SNGMSGPGM MSG('Iteration') ENDFOR

This loop will iterate 10 times, displaying a message on each iteration.

More control flow statements can be found here: https://www.ibm.com/docs/en/i/7.5?topic=programming-controlling-processing-within-cl-program-cl-procedure


Monitoring for Errors: MONMSG

CL programs can monitor for errors using the MONMSG (Monitor Message) command. This allows you to handle exceptions gracefully instead of letting the program terminate unexpectedly.

PGM
MONMSG MSGID(CPF0000) EXEC(DO) SNGMSGPGM MSG('An error occurred') ENDDO /* Normal commands here */ ENDPGM
  • MONMSG MSGID(CPF0000): Monitors for any system message starting with CPF.
  • EXEC(DO): Executes the commands inside the block if an error occurs.

Best Practices for CLP Syntax and Structure

  1. Use Meaningful Variable Names: Choose variable names that reflect their purpose (e.g., &CUSTOMERNAME, &ORDERCOUNT).
  2. Indentation for Readability: Indent blocks of code inside DO/ENDDO and conditional statements for better readability.
  3. Comment Your Code: Add comments to explain the purpose of complex commands or logic.
  4. Monitor for Errors: Use MONMSG to handle potential errors and prevent program crashes.

Conclusion

The syntax and structure of CL programming are straightforward but powerful. With commands, variables, conditional logic, and loops, CL programs can automate complex tasks on IBM i. By following the guidelines and best practices outlined in this article, you are now equipped to start writing well-structured CL programs.

In the next article, we’ll dive deeper into Data Types and Variables in CL programming, covering how to use them effectively to manipulate data in your programs. Stay tuned for more! 

Thursday, 10 October 2024

Introduction to IBM i and CL

Welcome to the first step of your journey into CL programming! In this article, we will provide an in-depth introduction to IBM i, often known as AS400, and the role of CL (Control Language) within the system. By understanding the foundational concepts of IBM i and the role that CL plays in it, you’ll be well-equipped to begin writing your own CL programs.


What is IBM i?

IBM i is an operating system developed by IBM for its family of Power Systems hardware (formerly known as AS400). It is a robust, integrated, and highly secure platform widely used in enterprise environments for managing business-critical applications and data. The system has evolved over decades from its origins in the 1980s as the AS400, to becoming IBM iSeries, and is now referred to simply as IBM i.

IBM i is designed for both transactional and batch processing, supporting thousands of users simultaneously while ensuring high availability, reliability, and data integrity. It integrates a range of technologies, including databases, user interfaces, job scheduling, and networking, into one cohesive system. Companies across industries use it for enterprise resource planning (ERP), financial systems, and other critical applications.

Key Features of IBM i:

  • Integrated Relational Database (DB2 for i): The database is tightly integrated into the system, offering powerful data processing capabilities.
  • Object-Oriented Architecture: Everything in IBM i is an object, from files and programs to devices and jobs.
  • Security and Reliability: IBM i provides a high level of security, auditability, and operational stability, which makes it ideal for mission-critical applications.
  • Job Processing: The system is optimized for batch processing, job control, and multitasking operations.
  • Application Development Support: In addition to CL, IBM i supports a variety of programming languages, such as RPG, COBOL, Java, C, and C++.

What is CL (Control Language)?

CL, or Control Language, is a procedural language used primarily for interacting with the IBM i operating system. It is used to:

  • Automate repetitive tasks,
  • Control job flows,
  • Schedule batch jobs,
  • Manage system resources,
  • Execute commands that would otherwise be performed manually through the system’s command line interface.

CL scripts (also known as CL programs) are fundamental in managing the system’s behavior, controlling system jobs, and interacting with other system objects such as files, devices, and data queues.

The Role of CL in IBM i

  • Automation: Many tasks in IBM i, such as backups, reports, and data processing, can be automated through CL scripts.
  • Job Management: CL commands help manage jobs on the system, including starting, stopping, and monitoring them.
  • System Interaction: CL allows users and administrators to control the system programmatically rather than manually typing commands.
  • File and Database Handling: CL programs interact with the system’s database files, handling records, data queues, and objects efficiently.

In essence, CL acts as a glue between the user (or other programs) and the core functionality of the IBM i system, enabling robust automation and system control.


Understanding IBM i Objects

Before we dive into CL itself, it’s important to understand the concept of objects in IBM i. IBM i is built on an object-based architecture, where every component of the system is treated as an object.

Some common types of objects in IBM i include:

  • Programs (*PGM): Executable code, including CL programs and RPG applications.
  • Files (*FILE): Objects that hold data, including database files, source files, and device files.
  • Libraries (*LIB): Containers for grouping related objects.
  • Messages (*MSG): Messages sent between programs, jobs, or users.
  • Devices (*DEVD): Hardware resources like printers and disk drives.
  • User Profiles (*USRPRF): Objects representing system users and their permissions.

Libraries and Object Storage

In IBM i, objects are stored in libraries, which serve as logical containers for organizing resources. Libraries themselves are also objects, and there is a system library list that the operating system uses to search for objects. When working with CL, you’ll interact with libraries frequently as you manage the location and accessibility of various objects.


The Structure of a CL Program

A CL program is a sequence of CL commands that execute specific tasks. The structure is relatively simple, making it easy for both beginners and advanced users to pick up and automate tasks.

Here’s a basic structure of a CL program:

PGM /* Start of the CL program */ /* Variable declarations and initializations */ /* CL commands for processing */ ENDPGM /* End of the CL program */

Each line in a CL program typically begins with a CL command, followed by parameters. For example, a simple CL program to display a message on the screen might look like this:

PGM SNGMSGPGM PGM('Hello, World!') ENDPGM

This program uses the DSPLY command to display a message. We’ll explore such commands in more detail later in the series.


Command Entry and Prompting

IBM i provides several ways to execute CL commands:

  • Command Line: You can manually type commands at the command line (accessible via a terminal or emulator).
  • Programs: You can group multiple commands into a CL program, which can be executed as a single entity.
  • Batch Jobs: CL commands can be executed as part of a batch job, running in the background without user interaction.

One of the great features of CL is command prompting. When you type a command but aren't sure of its parameters, you can press F4, and IBM i will display a prompt with fields for all available parameters, helping you construct the command correctly.

For example, typing DSPLIB and pressing F4 will bring up a prompt for the Display Library command, where you can enter or select the parameters.


The Importance of CL in Daily Operations

For IBM i administrators, CL is indispensable. Here are some typical tasks that can be automated or controlled through CL:

  • Job Scheduling and Monitoring: Automating the execution of batch jobs using CL commands like SBMJOB (Submit Job).
  • Backup and Recovery: Automating system backups and restoring data using CL scripts.
  • File Management: Managing system files, moving data between environments, and processing files automatically.
  • Security and User Management: Managing user profiles, setting authorities, and auditing system activities through CL programs.

Many organizations with IBM i systems rely on CL for their critical processes. For instance, daily financial reports, system monitoring, and large-scale batch processing are often done using CL scripts.


Tools for Writing and Executing CL Programs

SEU (Source Entry Utility)

Historically, the Source Entry Utility (SEU) was used for writing CL programs. SEU is an editor for creating and maintaining source files on IBM i. However, it is now considered legacy, and most developers use more modern alternatives like RDi (Rational Developer for i).

RDi (Rational Developer for i)

Rational Developer for i is an Eclipse-based integrated development environment (IDE) that offers more robust features like code syntax highlighting, debugging tools, and an enhanced user experience compared to SEU.

PDM (Program Development Manager)

The Program Development Manager (PDM) is a tool used to manage source files, objects, and libraries. It allows developers to compile, run, and manage programs from a single interface.

Running CL Programs

Once written, a CL program can be compiled into an executable object using the CRTCLPGM command (Create CL Program). After compilation, it can be executed directly or scheduled to run in the background using commands like SBMJOB.


Conclusion

With this introduction to IBM i and Control Language (CL), you now have a solid understanding of the system and the role that CL plays. From managing jobs and automating tasks to controlling system resources, CL is an invaluable tool in the IBM i environment. As we progress, we’ll delve deeper into specific topics, starting with how to create your first CL program and exploring more advanced concepts.

In the next article, we’ll take our first steps by setting up the development environment and writing a basic CL program. Stay tuned as we start building your CL expertise from the ground up!

Introduction to CL Programming on IBM i (AS400)

Welcome to this comprehensive guide on CL Programming (CLP), the Command Language Programming used in IBM i (previously known as AS400). CL is an essential part of the IBM i platform, acting as a bridge between users and the system’s powerful features. Whether you're a beginner or have experience with IBM i, this guide will help you master the art of CL programming.

What is CL Programming?

CL (Control Language) is a scripting language designed to interact with the IBM i operating system. It's commonly used to automate tasks, control job flows, manage system resources, and execute system commands. Mastering CL helps you maximize the efficiency of an IBM i environment, especially when dealing with batch processing, job scheduling, or system management tasks.

Why Learn CL?

Learning CL is crucial for several reasons:

  • Efficient Job Control: Automating and controlling jobs on IBM i with CL can simplify workflows.
  • Integration with RPG: CL programs are often used in combination with RPG programs to handle system-level tasks, making it a versatile skill for IBM i professionals.
  • System Administration: CL scripts allow for task automation, monitoring, and resource management, making system administration much smoother.
  • Legacy Code Maintenance: Many businesses still use CL code. Understanding it helps maintain and modernize legacy systems.

Structure of this Tutorial

This blog will walk you through everything from basic concepts to advanced techniques. Below is a detailed index that will guide your learning journey. You can refer back to this page anytime to jump between topics.


Index: Comprehensive CL Programming Guide

1. Getting Started with CL Programming

  • Introduction to IBM i and CL
  • CLP Syntax and Structure Overview
  • Setting Up Your Development Environment
  • Creating Your First CL Program

2. Basic CL Commands

  • WRKOBJ (Work with Objects)
  • CRTCLPGM (Create CL Program)
  • RUNSQLSTM (Run SQL Statements)
  • SNDPGMMSG (Display Message)
  • SNDMSG (Send Message)

3. Working with Variables

  • Declaring and Initializing Variables
  • Using System-Defined Variables
  • Manipulating Variables in CL

4. Input/Output Operations

  • Reading and Writing to Data Areas
  • File I/O Operations in CL
  • Using Data Queues for Inter-Program Communication

5. Control Structures in CL

  • Conditional Statements: IF, ELSE, DO
  • Looping with DOWHILE and FOR
  • Error Handling with MONMSG (Monitor Message)

6. File Handling in CL

  • Handling Database Files in CL
  • Opening and Closing Files
  • Reading Records with RCVF (Receive File)
  • Updating and Writing Records in CL

7. Job and System Control

  • Submitting Jobs with SBMJOB
  • Controlling Jobs with WRKJOB and ENDJOB
  • Scheduling Jobs with WRKJOBSCDE
  • Working with Job Queues

8. Message Handling in CL

  • Sending and Receiving Messages in CL Programs
  • Handling System Messages
  • Using Message Queues for Communication

9. Error Handling and Debugging

  • Monitoring Errors with MONMSG
  • Debugging Techniques for CL Programs
  • Using STRDBG (Start Debug) to Test Programs
  • Handling System Errors and Program Failures

10. Subroutines and Modularity

  • Creating Subroutines in CL Programs
  • Best Practices for Modular CL Code
  • Using CALL and CALLSUBR to Invoke Procedures

11. Advanced Techniques

  • Using APIs in CL Programs
  • Integrating CL with RPG and COBOL
  • Using QShell Commands in CL
  • Handling Complex File Operations and Data Transfers

12. Working with System Objects

  • Object-Oriented Concepts in IBM i
  • Creating, Deleting, and Modifying Objects
  • Understanding Libraries, Files, and Members

13. System Security and CL

  • Working with User Profiles and Authorities
  • Auditing System Activities with CL
  • Automating Security-Related Tasks

14. Performance Optimization

  • Improving Performance of CL Programs
  • Batch Processing and Parallel Execution
  • Memory and Resource Management in CL

15. Real-World CL Examples

  • Automating Backup and Recovery Processes
  • Managing System Logs and Reports
  • Batch Processing of Financial Data
  • System Monitoring and Alerting with CL

16. Best Practices and Tips

  • Coding Standards for CL
  • Error Handling and Logging
  • Performance Tuning Techniques
  • Maintaining Legacy CL Code

Next Steps

In the upcoming articles, we will start by setting up the development environment, learning the syntax, and creating simple programs. Bookmark this page to stay updated as new sections are published, and feel free to explore the index to find topics of interest.

Whether you're preparing for a role in system administration, development, or support on IBM i, this guide will be your companion throughout the learning process. Let’s dive into CL programming and unlock the potential of IBM i!

Thursday, 3 October 2024

Basic Syntax Structure in Free Format RPG

 

Introduction

With the advent of free format RPG, the structure and syntax of the language have become far more intuitive and developer-friendly. No longer confined by the fixed columnar format of earlier RPG versions, free format allows programmers to write code in a modern, clean, and flexible style. This flexibility makes the language easier to learn, more readable, and more efficient in enterprise-level development on IBM i (AS/400).

In this article, we will cover the basic syntax structure in free format RPG, including:

  • Control options (ctl-opt)
  • Declaration specifications (dcl-s, dcl-c, dcl-f, dcl-pr, dcl-pi)
  • Operators and expressions
  • Flow control structures (if, select, loops, etc.)
  • Procedures and subprocedures
  • Comments and best practices for readability

By the end of this article, you will understand how free format RPG is structured and how to write clean, maintainable code.


1. Control Options (ctl-opt)

Control options in free format RPG are used to define global settings for the program. These settings apply to the entire RPG module and influence how the program behaves during compilation and execution. In older RPG versions, these were specified using header specifications (H-specs). However, in free format, the control options are declared with the ctl-opt keyword.

Common Control Options:

  • dftactgrp(*no): Disables the default activation group.
  • actgrp(*new): Specifies a new activation group for the program.
  • main(): Defines the entry point of the program.
  • debug(*yes): Enables debug options.
  • bnddir(): Specifies a binding directory for external procedures or service programs.

Example:

ctl-opt dftactgrp(*no) actgrp(*new) main(mainProc);

This example defines that the program will not use the default activation group, creates a new one, and specifies mainProc as the entry procedure of the program.


2. Declaration Specifications

Declarations are a critical part of any RPG program. They define variables, constants, files, procedures, and prototypes. In free format, declaration statements no longer need to adhere to column restrictions, and they are more expressive and readable.

2.1 Declaring Variables (dcl-s)

Variables in free format RPG are declared using the dcl-s (declare scalar) keyword, followed by the variable name, its data type, and optional initialization.

Example:

dcl-s customerName char(50); dcl-s totalAmount packed(9:2) inz(0); // Initialized to 0 dcl-s taxRate packed(5:2) inz(0.07); // Initialized to 7%

Here, we declare:

  • customerName: A character string of length 50.
  • totalAmount: A packed decimal with 9 digits, 2 decimal places, initialized to 0.
  • taxRate: A packed decimal with 5 digits, 2 decimal places, initialized to 0.07.

2.2 Declaring Constants (dcl-c)

Constants are defined using the dcl-c (declare constant) keyword. Constants, once defined, cannot be changed during the execution of the program.

Example:

dcl-c PiValue float(8) value(3.1415926535); dcl-c Message char(20) value('Welcome to RPG!');

In this example:

  • PiValue: A constant holding the value of Pi.
  • Message: A constant string initialized with the text "Welcome to RPG!".

2.3 Declaring Files (dcl-f)

Files (both input and output) are declared using the dcl-f (declare file) keyword. File declarations specify the access method (*input, *output, *update, etc.), and the file type (e.g., DISK, PRINTER, WORKSTN).

Example:

dcl-f CustomerFile usage(*input) keyed; dcl-f ReportFile printer oflind(*inof);
  • CustomerFile: Declares a file for input with keyed access (e.g., an index for direct access to records).
  • ReportFile: Declares a printer file used to generate reports, with an overflow indicator (*inof).

2.4 Declaring Prototypes (dcl-pr and dcl-pi)

Prototypes allow you to declare procedures that may be external or internal to the program. Prototypes help define the signature of a procedure—what parameters it takes and what value it returns.

  • dcl-pr: Declare procedure prototype.
  • dcl-pi: Declare procedure interface (the actual procedure).

Example:

// Procedure prototype dcl-pr CalculateTotalAmount packed(9:2); baseAmount packed(9:2); taxAmount packed(9:2); end-pr; // Procedure interface dcl-pi CalculateTotalAmount packed(9:2); baseAmount packed(9:2); taxAmount packed(9:2); end-pi;

In this example, we declare:

  • CalculateTotalAmount: A procedure that takes two packed decimal parameters (baseAmount and taxAmount) and returns a packed decimal with 9 digits and 2 decimal places.

3. Operators and Expressions

Free format RPG supports various operators to perform calculations, comparisons, and logical operations.

3.1 Arithmetic Operators:

  • +: Addition
  • -: Subtraction
  • *: Multiplication
  • /: Division

Example:

totalAmount = baseAmount + (baseAmount * taxRate);

This expression calculates the total amount by adding the tax to the base amount.

3.2 Comparison Operators:

  • =: Equal to
  • <>: Not equal to
  • >, <: Greater than, less than
  • >=, <=: Greater than or equal to, less than or equal to

Example:

if totalAmount > 1000; dsply 'Large order'; endif;

Here, the program checks if totalAmount is greater than 1000, and if so, displays a message.

3.3 Logical Operators:

  • and: Logical AND
  • or: Logical OR
  • not: Logical NOT

Example:

if isMember and hasDiscount; discountAmount = totalAmount * discountRate; endif;

This example calculates a discount only if both conditions—isMember and hasDiscount—are true.


4. Flow Control Structures

4.1 Conditional Statements: if, elseif, else

Conditional logic allows the program to make decisions based on conditions.

Example:

if orderValue > 1000; dsply 'High-value order'; elseif orderValue > 500; dsply 'Medium-value order'; else; dsply 'Low-value order'; endif;

The if block checks conditions in sequence and executes the appropriate block of code.

4.2 select / when

The select / when structure allows for multi-condition checks similar to a switch-case in other languages.

Example:

select; when orderType = 'A'; dsply 'Type A order'; when orderType = 'B'; dsply 'Type B order'; other; dsply 'Unknown order type'; endselect;

Here, select provides a way to handle different cases based on the value of orderType.

4.3 Loops: for, dow, dou

Loops allow for repetitive execution of code until a condition is met.

for Loop Example:

for counter = 1 to 10; dsply counter; endfor;

This loop runs from 1 to 10, displaying each value of counter.

dow (Do While) Example:

dow totalSales < targetSales; totalSales += dailySales; enddo;

The loop continues as long as totalSales is less than targetSales.

dou (Do Until) Example:

dou totalSales >= targetSales; totalSales += dailySales; enddo;

This loop runs until totalSales reaches or exceeds targetSales.


5. Procedures and Subprocedures

Procedures allow for modular programming by separating logic into reusable blocks of code.

Defining a Procedure:

dcl-proc CalculateDiscount; dcl-pi *n packed(9:2); baseAmount packed(9:2); discountRate packed(5:2); end-pi; return baseAmount * discountRate; end-proc;

Here, CalculateDiscount is a procedure that calculates the discount based on the base amount and the discount rate.

Calling a Procedure:

discount = CalculateDiscount(totalAmount : discountRate);

Procedures improve code organization and reusability.


6. Comments and Best Practices

Comments are essential for making the code readable and understandable by other developers or for future reference. In free format RPG, comments start with two slashes (//).

Example:

// Calculate total amount with tax totalAmount = baseAmount * (1 + taxRate);

Best Practices:

  • Use meaningful variable names: Variables like totalAmount and baseAmount convey their purpose clearly.
  • Break complex logic into procedures: Modularize your code using procedures and subprocedures.
  • Comment your code: Ensure that key logic is explained for readability and maintainability.

Conclusion

The basic syntax structure of free format RPG is clean, flexible, and modern, allowing developers to focus on business logic rather than syntax constraints. Understanding the basic components like control options, declarations, operators, and flow control structures is the foundation for mastering RPG in its free format style.

As you progress, you will see how this syntax forms the backbone of more complex applications and enterprise solutions on IBM i.

The Evolution from Fixed to Free Format RPG

 

Overview

RPG (Report Program Generator) has undergone several significant transformations throughout its long history, but none have been as revolutionary as the shift from fixed format to free format. Originally developed as a tightly structured, column-based language, RPG was once notorious for its rigid syntax, where every piece of code had to be written in specific columns on a line. However, with the advent of RPG IV and eventually free-format RPG, the language shed much of its historical baggage, embracing a more modern, flexible, and readable style.

This article explores the key phases in RPG's evolution from fixed to free format, emphasizing the impact this shift has had on how developers write, maintain, and think about RPG code.


1. The Fixed Format Era: Constraints and Structure

The Legacy of Column-Based Coding

In the early days of RPG (starting with RPG II), the language was strictly column-based, inheriting a lot of its formatting rules from the punch card systems in use at the time. Each line of code was divided into specific columns, and each column had a defined purpose. Deviating from these rules would lead to syntax errors, making the development process cumbersome and unintuitive, especially for new programmers.

Column Design in Fixed Format

Here’s how the columns were generally used in traditional fixed-format RPG:

  • Columns 1-5: Sequence numbers for punch card operations or for editing convenience.
  • Column 6: Continuation indicator to signal that the line of code continues from the previous line.
  • Columns 7-8: Specification type, which indicated the type of operation (C for calculation, H for header, I for input, etc.).
  • Columns 9-11: Factor 1 – first operand (optional depending on the operation).
  • Columns 12-13: Operation code (e.g., ADD, SUB, CHAIN, etc.).
  • Columns 14-24: Factor 2 – the second operand or constant to be used in the operation.
  • Columns 25-35: Result field where the result of the operation was stored.
  • Columns 36-80: Comment area or indicator fields.

Here’s an example of a basic fixed-format RPG IV code snippet:

C 'HELLO' DSPLY C *INLR SETON

Each line adheres to a strict structure, with operations (like DSPLY and SETON) tied to specific columns.

Drawbacks of Fixed Format

  1. Low Readability: Fixed format required that code be written in predefined columns, making it difficult for developers unfamiliar with RPG to understand. The code appeared cryptic, especially to those used to more modern languages like C or Java.

  2. Development Overhead: The need to manually place operations in specific columns created additional work. A simple syntax error, such as misaligning a column, could cause the entire program to fail or behave unexpectedly.

  3. Rigid Structure: Fixed-format RPG enforced a single way of writing code. This rigidity made the language harder to adapt to more complex, modern programming paradigms, such as modularity, object-oriented programming, or working with APIs.


2. RPG IV: A Turning Point

In 1994, IBM released RPG IV (also known as RPGLE), which marked a significant shift towards modernization. RPG IV introduced several major enhancements, but it was still rooted in fixed-format conventions, though with some relaxations and enhancements.

Key RPG IV Enhancements:

  1. Longer Variable Names: RPG IV allowed for variable names up to 4096 characters, a significant improvement over the previous limit of 6 characters. This increased the readability and self-documenting nature of the code.

  2. Expanded Data Types: RPG IV introduced new data types such as date, time, and timestamp, allowing for more sophisticated manipulation of time-based data.

  3. Modular Programming: The concept of procedures and modules was introduced in RPG IV, allowing developers to write modular, reusable code. This was a step towards more modern development methodologies.

  4. Embedded SQL: RPG IV allowed the direct use of SQL within RPG code, making it easier to interact with databases, a common requirement in enterprise applications.

Initial Steps Towards Free Format

While RPG IV still adhered largely to fixed-format conventions, IBM began loosening the rules:

  • Some operations, like calculation specifications, no longer required precise column alignment.
  • More complex data structures (arrays, data structures, etc.) were supported, opening up more flexibility for developers.

The following RPG IV example shows a slight relaxation from the rigid structure of earlier versions:

C EVAL result = x + y C IF result > 100 C EXSR print_large C ENDIF

While this version is more readable than earlier RPG versions, it still requires some alignment in columns.


3. The Introduction of Free-Format RPG

The major revolution came in 2013 when IBM introduced fully free-format RPG. This was a major overhaul that brought RPG in line with modern programming languages by abandoning the historical column restrictions entirely.

What is Free-Format RPG?

Free-format RPG is a style of RPG programming where the code is no longer constrained by specific column positions. Developers can write code in a much more natural and readable way, similar to languages like C, Java, or Python.

Here’s an example of how code written in free-format RPG looks:

dcl-s message char(50); message = 'Hello, Free Format RPG!'; dsply message; *inlr = *on;

As you can see, the code flows naturally from left to right without worrying about which column a particular instruction should be in. This significantly increases readability and reduces the overhead associated with writing RPG code.

Key Features of Free-Format RPG

  1. No Column Restrictions: Unlike fixed-format, there are no columns that dictate where specific instructions must begin. You can write code freely across the line.

  2. Structured Blocks: Free-format allows for the use of structured control statements (IF, DO, SELECT, FOR) in a way that is visually aligned and easier to follow.

  3. Enhanced Readability: Code written in free format looks much cleaner and is easier to understand for both RPG developers and those coming from other languages.

  4. Modern Control Structures: Free-format RPG supports modern control structures like FOR, WHILE, and DO-WHILE loops, bringing the language closer to other mainstream programming languages.

  5. Flexible Declarations: Declarations for variables, files, and data structures (DCL-S, DCL-F, DCL-DS) can be made without column alignment. Additionally, free-format RPG allows for in-line initialization of variables, further simplifying the code.

Fully Free-Format RPG Example:

ctl-opt dftactgrp(*no) actgrp(*new); dcl-s totalSales packed(15:2); dcl-s discountRate packed(5:2) inz(0.05); dcl-s finalPrice packed(15:2); totalSales = 1000.00; finalPrice = totalSales * (1 - discountRate); if finalPrice > 900.00; dsply ('High Discount Applied'); endif; *inlr = *on;

This example demonstrates the clean and easy-to-read syntax in free-format RPG. You no longer need to align your code in specific columns, making it easier for developers to focus on logic rather than format.


4. Transitioning from Fixed to Free Format: Benefits and Challenges

Benefits of Free Format RPG

  1. Improved Developer Productivity: Free format allows developers to write code faster and with fewer errors, as they no longer need to adhere to column-based rules.

  2. Enhanced Maintainability: Free-format code is easier to read and maintain, allowing teams to understand the business logic without getting bogged down by formatting concerns.

  3. Better Integration with Modern Tools: Free format integrates well with modern development environments such as RDi (Rational Developer for i), offering features like syntax highlighting, code folding, and inline debugging.

  4. Attracting New Developers: Free format makes RPG more approachable for developers who are familiar with other modern programming languages, helping businesses maintain and grow their RPG talent base.

Challenges of Transitioning

While free format is a significant improvement, organizations that have legacy systems with fixed-format RPG face challenges:

  1. Legacy Code: Many enterprises still have large codebases in fixed format. Converting these systems to free format can be time-consuming and risky without proper planning.

  2. Skill Gap: Some experienced RPG developers who are used to fixed format might initially resist the switch to free format due to familiarity with the old style.


5. RPG Free Format Today and Its Future

The move to free-format RPG has cemented the language's place in modern enterprise environments. While the AS/400 and its descendants (now IBM i) remain popular in industries like manufacturing, logistics, finance, and healthcare, the transition to free format ensures that RPG remains relevant and adaptable to modern IT practices.

Modern Use Cases

  • Web Services and APIs: Free-format RPG allows for easier integration with web services (REST/SOAP) and the use of JSON/XML data formats.

  • Database-Driven Applications: RPG remains a strong contender for applications that require heavy interaction with IBM Db2 databases.

  • Cloud and Hybrid Environments: As IBM i evolves to support cloud and hybrid infrastructures, free-format RPG is well-positioned to handle these new deployment models.


Conclusion

The evolution from fixed to free format RPG is one of the most transformative changes in the history of the language. By abandoning the constraints of column-based formatting, free-format RPG has brought a new level of flexibility, readability, and modernity to a language that’s been serving businesses for over half a century. For developers familiar with traditional RPG, the transition to free format might seem daunting, but the long-term benefits in terms of productivity, maintainability, and ease of integration with modern tools make it a critical step forward.

As we move deeper into this tutorial, we will explore the syntax and best practices for writing free-format RPG, giving you the tools to transition effectively and embrace the power of this modernized language.

What is RPG? - Understanding the Origins, Evolution, and Modern RPG

RPG (Report Program Generator) is a high-level programming language developed by IBM in 1959 for generating business reports. Over the years, it has grown into a full-fledged general-purpose programming language, especially prominent in the IBM i (formerly AS/400) ecosystem. Although it started as a tool for producing reports from business data, RPG has continuously evolved, keeping pace with modern development practices, particularly with the introduction of RPG IV and its free-format syntax.

In this article, we will explore:

  • The origins and history of RPG
  • Evolution from RPG II to RPG IV
  • The transition from fixed format to free format
  • Modern uses of RPG on IBM i
  • Why RPG is still relevant today

The Origins of RPG

RPG was originally designed in the late 1950s by IBM as a simpler alternative to assembly language. At the time, businesses were looking for a more efficient way to generate reports from data stored in punch cards and magnetic tapes. IBM introduced RPG as a high-level tool that could describe and generate business reports with minimal programming effort.

Early RPG: Punch Cards and Business Reports

RPG's name comes from its original function: Report Program Generator. Early versions of the language were designed to generate detailed reports from data stored in tabular form. Instead of coding individual instructions, developers could describe the format of a report, and RPG would handle the mechanics of pulling data and formatting it.

The early language was highly structured, and programs were designed to process one record at a time, read from sequential data files. Programmers would use punched cards with fixed columns to define operations, and every line of code adhered strictly to this rigid format.

RPG I and RPG II (1960s - 1970s)

RPG I, the earliest version, quickly became popular for producing business forms, invoices, and financial reports. In 1969, IBM released RPG II, which expanded the language to include more advanced features for data processing, such as indexed file access, conditional logic, and basic arithmetic operations.

Despite its improvements, RPG II remained very rigid in its structure, requiring specific columns for code and making it difficult to read, especially compared to modern languages.


The Evolution of RPG: From RPG III to RPG IV

RPG III (1978)

In the late 1970s, IBM introduced RPG III as part of its System/38 platform, a precursor to the AS/400. RPG III was a major step forward, allowing for more complex data structures, better control over file access, and new ways to organize logic using subroutines.

The structure of RPG III was still fixed-format, meaning that developers had to adhere to column-based code entry, but the language introduced a more modular approach to program design.

The Birth of AS/400 and RPG/400 (1988)

The launch of IBM’s AS/400 in 1988 was a milestone for RPG. The AS/400 became a popular platform for mid-sized businesses and enterprises to manage their IT infrastructure, and RPG/400 became the dominant language used on the platform.

RPG/400 was essentially an enhanced version of RPG III, optimized for the AS/400 environment, but still firmly based on fixed-format coding practices.


The Introduction of RPG IV and Free Format

RPG IV (1994): A New Beginning

The 1990s saw a massive overhaul of RPG with the introduction of RPG IV (also called RPGLE, where LE stands for Integrated Language Environment). RPG IV introduced many modern programming concepts, such as:

  • Longer variable names (up to 4096 characters)
  • Procedures and modules (allowing for modular, reusable code)
  • Support for data types like date, time, and timestamp
  • Integration with other languages, including C and SQL

RPG IV was a massive improvement in terms of readability, functionality, and flexibility. It also marked a shift away from column-specific coding toward a more modern and flexible approach.

However, even in RPG IV, the language was still primarily fixed-format, meaning that although the functionality had expanded, developers still needed to follow specific column rules when writing code.


Free Format RPG (2013): Embracing Modern Syntax

In 2013, IBM introduced fully free-format RPG, fundamentally changing how the language looked and felt. With free format, RPG finally shed its historical reliance on fixed columns, aligning with modern coding practices.

Key Features of Free Format RPG:

  1. No Column Restrictions: Code is no longer constrained by specific columns. Instead, you can write code freely, as with other modern languages like Java, Python, or C.
  2. Enhanced Readability: The code is easier to read and write. Developers can use indentation, spaces, and line breaks however they see fit, making the code much more maintainable.
  3. Simplified Syntax: Free format eliminates much of the archaic syntax and introduces clearer, more intuitive instructions.
  4. Integration with Modern Tools: Free format RPG works seamlessly with modern development tools such as Rational Developer for i (RDi), bringing advanced code editing, debugging, and refactoring tools to the RPG development process.

Here's a quick comparison of fixed-format RPG and free-format RPG:

Fixed Format RPG IV Example:

C 'HELLO' DSPLY C *INLR SETON

Free Format RPG Example:

dcl-s msg char(10) inz('HELLO'); dsply msg; *inlr = *on;

As you can see, the free format version is much more readable and intuitive, removing the old constraints of column-based coding and introducing variable declarations (dcl-s) and inline operations (dsply).


Modern RPG and Its Uses

Today, RPG on IBM i is a powerful language used for building and maintaining mission-critical applications in sectors such as finance, healthcare, logistics, and manufacturing. Many businesses continue to use RPG because of its stability, integration with IBM's robust platforms, and the legacy systems they still depend on.

Typical Use Cases for RPG:

  1. Enterprise Resource Planning (ERP) Systems: RPG is often used to develop and maintain ERP systems, where it handles massive amounts of transactional data reliably.
  2. Data Processing Applications: RPG’s original strength in data processing makes it ideal for applications where large datasets need to be processed and reported.
  3. Web Services and APIs: RPG can be integrated with web services, allowing businesses to expose and consume APIs, making it adaptable to modern web architectures.
  4. SQL Integration: RPG can natively embed SQL for advanced data manipulation, making it an excellent tool for database-heavy applications.

Why RPG is Still Relevant Today

Despite the explosion of new languages and technologies, RPG remains relevant in the IT world for several reasons:

  1. Legacy Systems: Many large enterprises still rely on RPG-based applications that were developed decades ago, and replacing or rewriting these systems would be prohibitively expensive.
  2. Reliability and Performance: RPG programs running on IBM i are known for their exceptional reliability and performance. They handle complex workloads with ease, making them a trusted tool for mission-critical operations.
  3. Modernization: With free format and integration with modern tools, RPG has modernized itself to remain competitive, giving long-time developers a way to bring legacy systems into the 21st century without completely rewriting codebases.

Conclusion

RPG has come a long way from its origins as a report generator for punch cards. Today, it's a versatile, high-level language capable of handling a wide range of applications, from enterprise resource planning to web services. With the introduction of free format RPG, the language has embraced modern development practices, making it easier to learn, write, and maintain.

In this tutorial series, we will continue exploring RPG free format in detail, starting with its syntax, setup, and how you can leverage it in the IBM i environment.

Introduction to RPG Free Format

 

Welcome to RPG Free Format!

RPG (Report Program Generator) has evolved significantly since its inception in the 1960s. Once tied to fixed formats and punch cards, it has now become a versatile and modern programming language with a free-format style that is intuitive and readable. If you are new to RPG or transitioning from an older version, this tutorial series will guide you step-by-step in learning RPG free format from the ground up.

Why Learn RPG Free Format?

  1. Ease of Use: Modern RPG has shed its archaic structure, making the language readable and concise.
  2. Industry Relevance: RPG is the backbone of many enterprise-level applications, especially in IBM's Power Systems and AS/400 environments.
  3. Versatility: With RPG's free-format, you'll have the flexibility to write more modular and maintainable code, integrating with modern technologies such as SQL and web services.

Who Is This For?

Whether you're a seasoned developer looking to modernize your RPG skills or a complete newcomer to the language, this series is for you. We’ll start with the basics and gradually move into more advanced topics, ensuring a comprehensive understanding.

How to Navigate the Tutorial Series

The articles in this tutorial series are designed to be read in sequence, but you can also refer back to any specific topic using the index below. The tutorials are structured to build on each other, so we recommend starting from the beginning if you're unfamiliar with RPG Free Format.


Index: Mastering RPG Free Format

  1. Introduction to RPG and Free Format Syntax

    • What is RPG?
    • The evolution from fixed to free format
    • Basic syntax structure in free format
    • Tools for RPG development (IDEs and compilers)
  2. Setting Up the Development Environment

    • Installing an RPG-compatible IDE (e.g., RDi)
    • Connecting to IBM i Systems
    • Using PDM and SEU vs modern IDEs
  3. Basic Program Structure in RPG

    • The ctl-opt directive
    • File declarations: DCL-F
    • Variable declarations: DCL-S
    • Procedures and subprocedures
  4. Working with Variables and Data Types

    • Built-in data types (numeric, character, date, time)
    • Constants and literals
    • Conversion between data types
    • Special built-in functions
  5. Control Flow in RPG

    • IF, ELSE, and ENDIF constructs
    • DO and FOR loops
    • SELECT and WHEN structures
    • Error handling: MONITOR, ON-ERROR, and ENDMON
  6. File I/O Operations in RPG

    • Reading and writing physical files
    • CHAIN, READ, WRITE, UPDATE, DELETE
    • Handling keyed and non-keyed access
    • Working with multi-format logical files
  7. Working with Arrays and Data Structures

    • Defining and manipulating arrays
    • Data structures: DCL-DS and nested structures
    • Multi-dimensional arrays
    • Data structure I/O operations
  8. Subprocedures and Modular Programming

    • Creating and calling subprocedures
    • Passing parameters by value and reference
    • Modularizing code for reusability
    • Local vs global variables
  9. Error Handling and Debugging

    • Using MONITOR, ON-ERROR, and ENDMON
    • Error trapping and custom error messages
    • Debugging techniques in RDi and STRDBG
  10. Using SQL in RPG Programs

    • Embedding SQL in RPG
    • Executing SELECT, INSERT, UPDATE, DELETE
    • Using SQL cursors for advanced data manipulation
    • Performance considerations with SQL in RPG
  11. Advanced File Processing

    • Multi-member files
    • Processing join logical files
    • Working with data areas and data queues
    • IFS (Integrated File System) file operations
  12. Working with External APIs and Web Services

    • Consuming REST and SOAP APIs in RPG
    • Handling JSON and XML data
    • Using HTTP functions in RPG
    • Integrating RPG with web services
  13. Date and Time Operations

    • Manipulating date and time fields
    • Date arithmetic and formatting
    • Working with timestamps
    • Handling time zones in RPG
  14. Advanced String Handling

    • String manipulation functions (e.g., %SUBST, %TRIM, %SCAN)
    • Concatenation and substring operations
    • Working with long strings and varying-length fields
  15. Memory Management and Performance Optimization

    • Memory allocation strategies in RPG
    • Reducing memory usage with data structures
    • Performance tuning techniques
    • Analyzing and optimizing RPG code
  16. Legacy Integration and Migration Strategies

    • Migrating from fixed-format to free format RPG
    • Handling legacy codebases and systems
    • Strategies for modernizing old RPG applications
  17. Testing and Quality Assurance in RPG

    • Unit testing RPG code
    • Automated testing tools for RPG
    • Best practices for code reviews and testing
  18. Best Practices and Code Standards

    • Writing clean and maintainable RPG code
    • Naming conventions for variables, files, and procedures
    • Documentation and commenting best practices

In the coming weeks, we’ll dive into each topic in detail, providing code examples, explanations, and real-world scenarios to help you master RPG free format.

Stay tuned, and let’s embark on this journey of learning RPG together!