How to program an Application

From Try-AS/400
Revision as of 20:44, 8 February 2024 by Greenfive (talk | contribs) (fixed typos)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
Qsicon Fixme.png This article isn't finished yet or needs to be revised. Please keep in mind that thus it may be incomplete.

Reason: Finish article.

Getting started on programming the AS/400 isn't hard. According to Frank Soltis, the most effective way to get a machine sold is to actually bring an AS/400 along to the future customer, and show an CxO in a one hour crash course how to code a simple business application.
Well, something an arbitrary business buffoon can do, you can do, too. Since the usual Hello World is just too lame, let's start with an actually usable example: A simple address book application.

Components of a typical Program

Since we're talking about a database machine, the first we need to know is how to create Database Tables.

Editing Database Content is usually done in screen forms. These are called Display Files. So, let's also learn how to create Display Files in the next turn.

Finally, there must be a program for handling key presses from the user and coping with the I/O of database- and display files.

Optionally, there can be more files to support additional functions in a program. Printer files allow for formatted output (tabular report) to a printer. InterSystem Communication Files allow for Record-I/O to other programs on the local or a remote host. We will not dig into these, for now.

Programming Languages

Available on a full install of an older OS/400 are compilers for

and interpreters for

  • REXX, a scripting language derived from the mainframe world.

RPG and COBOL are available in two flavors: ILE and OPM. See linked explanations for details.

It makes no sense to utilize OPM compilers for new projects. It's best you save space and deinstall these as well as the *PRV variants, that generate code for the immediately previous OS release. We'll solely focus on ILE since it has (amongst others) the advantage of linking (binding) compiled object code from different languages together to form a program.

The IBM website features extensive documentation for each language.

A Word on Editors

If you are familiar with vi or vim on Unix-like platforms, learning SEU will be an easy task. You may alternatively utilize an editor of your choice on the platform of your choice.[2] To help you chose, we'll take a closer look on the pros and cons of each solution.

Editor Pro Con
SEU on OS/400 Built-in contextual support for many file types and kind of lines with precise column requirements.
Editing is done in an implicit array of blanks in permanent overwrite mode for easier placement of characters in proper position.
Can display only a few lines of code, that reduces clarity and thus forces a lot of scrolling.
Uniform colouring of code is increasingly uncommon and makes it even more difficult to keep an overview.
Other on other platforms Familiar operation and UI.
Easy content duplication with clearly visible text range selection, and copy-paste.
Possibility to create custom rules for syntax highlighting.
Cumbersome handling: After every change that should result in a compile run, changed files have to be transferred back in some way.

The Killer-Feature of SEU is the extensive contextual support it provides for RPG and DDS, and partly for COBOL. For beginners, it's much easier to utilize this helpful function often until some knowledge, routine and working programs as copy-source have been established.


Vim is most often the editor of choice for seasoned Text-UI affictionados. Since vim is able to open files on remote-locations via URL notation, you can perfectly use it for editing on the fly from any platform vim is available for. There are even extensions for syntax-highlighting of common code.[3] Automation of login can be done via ~/.netrc file:

  • Create/edit your ~/.vimrc to switch to ASCII mode on start, add:
let g:netrw_ftpmode="ascii"
  • Create/edit your ~/.netrc to have credentials ready, add:
machine my-machine-name
login myuser
password mypassword
macdef init

Important: The file must end with a blank line! Do a chmod 600 ~/.netrc for some more security.

  • Edit files giving vim the remote URL:
vim ftp://my-machine-name/mylib/mysrcpf.mymember

With this toolset, you can develop with a tall vim window on your desktop machine, klick on a 5250-session to compile and maybe have a second 5250 session open for running the program.


As you probably know from your experience with common systems, it's considered bad habit to work with administrative rights all of the time. I recommend Creating a User Account for you to properly work without accidentally doing harm to the system. Sign in as this user now. This gives you a subset of menu items in the main menu and makes your own Library your current library. For now, consider this almost the same thing as using the cd command of a shell to make a directory your current one.

As outlined in File Types, we'll need to create a file to hold source code. Let's do that and make the maximum line length a bit larger for more flexibility.[4]


The white text in the status line will show you that the file has been created.

Working with Members in Files

The easiest way to edit members of source files is to utilize part of the Program Development Manager.


You'll be presented with a screen form to handle members. Press F6 to show the Start SEU[5] screen. Fill out the two first fields:

  • SRCMBR is addrpf (for addresses physical file),
  • TYPE is pf for physical file.

Press Enter to start SEU and present an empty file.

Coding the Database Table

We're going to code the description of a database file, that is the traditional way to create database files in OS/400.[6] The language for the statements is called DDS[7] that is not a line oriented description like HTML. The position of statements within one line are also important.[8]

For an address book, let's assume the following fields are of primary interest:

  • Name,
  • First Name,
  • Birthday,
  • Street and Number,
  • ZIP Code and City Name,
  • Phone Number,
  • Cellular Phone Number,
  • E-Mail Address.

Plain DDS Code looks like this:

     A                                      UNIQUE
     A          R ADDRTBL
     A            NAME          48A
     A            FIRSTNAME     48A
     A            BIRTHDAY        L
     A            STREETNUM     48A
     A            ZIPCITY       48A
     A            PHONE         48A         ALWNULL
     A            CELLPHONE     48A         ALWNULL
     A            EMAIL         48A         ALWNULL
     A          K NAME
     A          K FIRSTNAME
     A          K BIRTHDAY

To understand a bit better, I'll elaborate.

As you can see, everything is written in upper case. To be honest, I don't know if a file with lower case characters in any place but comments is compilable.

Every line starts with an A in the 6th place of a line. The first five once were reserved for optional line numbering but I've seen no examples where this is actually done.

The first line denotes that this file may not have duplicate values in key fields (coded later).

The second line names this record format. This should be different from the file name. If not, you'll earn compiler warnings: In the actual program, when working with that file, it's ambiguous if you refer to the file name or the record format. For that reason, I name record formats for physical files with the suffix tbl.
Physical Files must have exactly one record format.

The next few lines define the fields of the database file. I don't want getting unnecessary initial complexity, so I defined all fields as character with static 48 places.[9] The Birthday-field is the only exception, that is defined as a date field.

Some fields may be left empty. To save space, these may be NULL, that is not the same as empty. Therefore they are defined with an additional parameter alwnull.
NULL fields permit fields of records to utilize no space at all, but need special attention in the code. This isn't as clumsy as coping with varlen strings, though.

The last three lines denote key fields. When reading records, they'll be retrieved in key order (ascending by default). According to the first line, entries must be unique over all key fields. So you may not have more than one entry named Fred Flintstone born on 1989-08-20. This is a somewhat crude way to prevent duplicates.[10]

After saving the member, one may type 14 into the field of the wrkmbrpdm members list to instruct it to compile the file with default values to the default location that is your current library.

A Word about the Compilation of Objects

Compilation per default takes place as background (batch) job that is more friendly to other tasks running in interactive mode but it's a bit clumsy to handle. One needs to look into the session's message queue to see if the compilation succeeded or failed, to be followed by a look into the spooled file, searching the verbose compiler output for possible culprits.
One may press F18 in the wrkmbrpdm screen to access another screen with user based defaults. The third option must be set to N.

See also


  • Helper Programs for the Fallout Role Playing Game Series
  • Templates for easy development of one-database-table maintenance programs


  1. Report Program Generator.
  2. Windows Notepad is not a proper editor. It's sufficient for notes, though. Hence the name.
  3. No longer working with vim 8.
  4. IBM delivers ready made, empty source files in the QGPL-Library. Every class of file has it's own source file, such as QCLSRC for CL source code. I consider this confusing: Working on multiple files is more cumbersome than working on multiple members of one file. The files in a member could be marked as a given type of content. The only drawback is that one must use distinct names on members. The QSYS.LIB-Filesystem can hold files with the same name as long as they have distinct types.
  5. Source Entry Utility.
  6. Database files can also be created with the interactive SQL facility, though. But one can't derive a textual description from a SQL created database file.
  7. Data Description Statements.
  8. This stems from old times when punch cards were used for programming stuff. Since compatibility is mandatory, IBM extended DDS from time to time with new keywords, but left the previous stuff alone.
  9. The AS/400 database knows about varchar field, but the handling in the code later would be really clumsy. So I refrain from that for now. Not used places are automatically filled with blanks.
  10. If Fred has more than one place to live, the right way to handle that would be to create a second table that lists every possible street address for a given Tuple Name—First Name—Birthday. Of course we might introduce entry IDs to keep the address table small. As said, I want to keep complexity low.