Welcome to the world of RPG file handling, where your programs stop being lonely loops and start talking to the database. In this lesson, we’ll explore how to define, read, write, and update files in RPGLE, using both externally-described and program-described formats.
Whether you're working with display files, printer files, or classic DISK-based tables, this chapter will give you the tools to make your RPG code data-aware and interactive.
Declaring Files with DCL-F
Every file in RPG starts with a DCL-F statement. This is your way of telling the compiler, “Hey, I’m going to use this file.” The syntax looks like this:
Device types include DISK, PRINTER, and WORKSTN. If you use a device keyword, it must be the first keyword after the file name.
A Simple RPGLE Read Example
Let’s create a file and read its contents. Run this command to generate a test file:
Replace MYLIB with your own library name. Then, compile and run this RPGLE snippet:
open rpgtestf;
read rpgtestf;
dow not %eof;
dsply ODOBNM;
read rpgtestf;
enddo;
close rpgtestf;
return;
Make sure to compile with DBGVIEW(*ALL) or DBGVIEW(*LIST) so you can debug with listing view and see where ODOBNM comes from.
Debugging Insights
Using RDI or STRDBG, switch to the Listing View to see the compiler-generated input specs. You’ll notice breakpoints only hit fields you actually use—like ODOBNM. That’s RPG optimization in action.
Externally-Described vs Program-Described Files
- Externally-described: RPG pulls the field layout from the file itself.
- Program-described: You define the layout manually in your code.
Example of a program-described printer file:
dcl-f qprint printer(QPRINT_LEN);
dcl-ds qprint_ds len(QPRINT_LEN) end-ds;
qprint_ds = 'Hello';
write qprint qprint_ds;
qprint_ds = 'world';
write qprint qprint_ds;
After running, check your spool files for a QPRINT output with two lines: “Hello” and “world.”
Implicit Open and Close
You can let RPG handle file opening and closing automatically:
read rpgtestf;
dow not %eof;
dsply ODOBNM;
read rpgtestf;
enddo;
Just remember: RPG only closes files when *INLR is set. Without it, your program might loop endlessly or leave files open across calls.
Writing and Updating Records
Use the USAGE keyword to control file access:
*INPUT(default)*OUTPUT*UPDATE*OUTPUT:*UPDATE
Update example:
read rpgtestf;
dow not %eof;
dsply 'new name' ODOBNM;
update QLIDOBJD;
read rpgtestf;
enddo;
Write Example:
ODOBNM = 'ABCDE';
write QLIDOBJD;
Use DSPFFD RPGTESTF to explore other fields you can populate before writing.
Exercises
Exercise: Remove *INLR, add RETURN. Call the program twice. Why does it only work once?
Solution: Without *INLR, the file stays open and at EOF. Add SETLL *START rpgtestf; before the loop to reset.
Exercise: Remove CLOSE, keep USROPN. Call the program twice. Why does it error the second time?
Solution: The file is still open. Add:
open rpgtestf;
endif;
