Built-in Functions

Built-in functions — BIFs — are RPG’s standard library. They’re always prefixed with %, so when you see %trim, %date, %eof, you know it’s a BIF rather than a procedure you wrote.

There are dozens. This chapter covers the ones you’ll use every day, grouped by what they do.

String manipulation

%trim, %trimr, %triml

name = %trim(SP_NAME);   // trim leading and trailing spaces
name = %trimr(SP_NAME);  // trim trailing only (right)
name = %triml(SP_NAME);  // trim leading only (left)

The most-used BIF in RPG. Database character fields are frequently space-padded; %trim removes the padding.

%len

nameLength = %len(%trim(SP_NAME));  // actual length of trimmed name
maxLength  = %len(SP_NAME);         // declared length of the field

Returns the current length of a varchar, or the declared length of a fixed-length char.

%subst

firstThree = %subst(productCode : 1 : 3);   // chars 1-3
tail       = %subst(productCode : 5);        // from position 5 to end

Substring extraction. Takes position and optional length. Positions are 1-based.

%scan, %scanrpl

pos = %scan('-' : productCode);              // position of first '-'
clean = %scanrpl('bad' : 'good' : message);  // replace all 'bad' with 'good'

%scan finds a substring’s position. %scanrpl replaces all occurrences.

%upper, %lower

normalized = %upper(userInput);
friendly   = %lower(headerText);

Case conversion.

%char, %dec

label = 'Qty: ' + %char(PR_QOH);          // number to char
price = %dec(priceString : 9 : 2);         // char to decimal, with precision

%char converts any type to its character representation. %dec converts character or numeric to packed decimal — with required precision arguments (digits:decimals).

Concatenation

message = 'Supplier ' + %trim(SP_NAME)
        + ' has ' + %char(productCount)
        + ' active products.';

Plain + concatenates strings. This is why you often see %char sprinkled in — to turn numbers into strings first.

File I/O status

%eof, %found

read SUPPLIER;
if %eof(SUPPLIER); leave; endif;

chain 'ACME001' SUPPLIER;
if not %found(SUPPLIER);
  dsply 'Supplier not found';
endif;

%eof — true if the last read hit end of file. %found — true if the last CHAIN (or similar positioning operation) found a match. Check these immediately after the operation — they change on the next I/O.

%error, %status

write SP_REC;
if %error;
  dsply ('Write failed with status: ' + %char(%status));
endif;

%error flags that the last operation raised an error. %status gives the numeric status code. More on these in Chapter 7.

Date and time

Briefly — full coverage in Chapter 8.

today  = %date();                  // today's date
now    = %time();                  // current time
stamp  = %timestamp();             // full timestamp
future = today + %days(30);        // 30 days from now
diff   = %diff(endDate : startDate : *days);  // days between

Numeric

%abs

variance = %abs(actual - expected);

Absolute value.

%int, %dec

whole = %int(decimalValue);         // truncate to integer
exact = %dec(amount : 11 : 4);      // convert to packed, specified precision

Control and lookup

%parms

if %parms() >= 2;
  // second parameter was passed
endif;

Number of parameters actually passed to the current procedure. Used with optional parameters.

%lookup

dcl-s regionCodes char(3) dim(50);
// ... regionCodes populated ...

idx = %lookup('NEU' : regionCodes);
if idx > 0;
  // found at position idx
endif;

Finds a value in an array. Returns the position or 0 if not found.

One habit worth building

When you’re writing expressions, reach for BIFs first. If you find yourself writing a loop to trim spaces, convert a type, or search a string, there’s almost certainly a BIF that does it in one line. Read the IBM RPG reference occasionally just to remind yourself what’s available — you’ll discover BIFs you didn’t know existed and simplify whole sections of code.

Next: Chapter 5: Embedded SQL.