RPGLE %SUBST Reference

%subst is the RPGLE built-in function for taking part of a string, and it can also be the target of an assignment to change part of one. This page gives the syntax, the rules for the start and length arguments, both uses, and the range errors to avoid.

It is a focused page. The other string functions are in the RPGLE String BIFs Reference, and parsing patterns built from several of them are in ILE RPG String Handling.

All examples are free-form RPGLE. Positions in a string start at 1.

Syntax

%subst(string : start {: length})
ArgumentMeaning
stringThe source. Character, graphic or UCS-2 data
startThe first position of the part you want. Must be greater than zero
lengthHow many characters to take. Can be zero. If omitted, the part runs to the end of the string

When you leave out the length, it is the length of the string minus the start value plus one. start and length can be any numeric value or expression with no decimal places. The last argument can also be *NATURAL or *STDCHARSIZE, which choose whether positions count characters or bytes for that statement.

Getting a substring

Used for its value, %subst returns the part of the string you ask for.

dcl-s greeting varchar(20) inz('Hello World');
dcl-s part varchar(20);

part = %subst(greeting : 7);            // 'World'
part = %subst(greeting : 7 : 3);        // 'Wor'
part = %subst('abcd' + 'efgh' : 4 : 3); // 'def'

The first argument can be a field or any character expression. When the part you want always starts at position 1, %left says the same thing more directly, and %right takes the end of a string.

Range rules and variable-length fields

The start position must be at least 1, and the part must lie inside the string. A start or length that reaches past the string is a run-time error, not a shorter result.

What “inside the string” means depends on the field type:

  • A fixed-length field is always its full declared length, padded with blanks.
  • For a varying-length field, the start and length are checked against its current length, not its maximum.
dcl-s fixedTxt char(10) inz('Hi');
dcl-s varTxt varchar(10) inz('Hi');
dcl-s part varchar(10);

part = %subst(fixedTxt : 1 : 5);        // 'Hi' and three blanks: inside the 10 bytes
monitor;
  part = %subst(varTxt : 1 : 5);        // error: the current length is 2
on-error;
  part = '*ERR';
endmon;

The error is a normal run-time exception, so a monitor group can handle it. This page does not give a message ID for it. The better habit is to calculate the length first, with %len or %scan, and never ask for characters beyond it.

A length of zero is allowed and returns an empty string. A start of zero is not allowed.

%SUBST on the left of an assignment

%subst can also receive a value. Used this way, it names part of a variable, and the assignment changes only those positions.

dcl-s a char(15) inz('abcdefghijklmno');

%subst(a : 3 : 4) = '****';             // 'ab****ghijklmno'

The rules differ from the value form:

  • The first argument must be a storage location: a field, data structure, subfield, array, array element or table element. An expression such as a literal does not qualify.
  • If you leave out the length, the target runs to the end of the string.
  • A length that reaches past the end of the string is a run-time error.
  • The start and length can be any expressions, but they cannot be unindexed arrays.
  • In CHARCOUNT NATURAL mode, the length argument is not allowed on the left side.

The target is treated like any other character target. A shorter value is padded with blanks and a longer one is cut to fit the part you named.

dcl-s a char(15) inz('ab****ghijklmno');

%subst(a : 13) = 'XY';                 // positions 13 to 15 become 'XY' and a blank

Taking text on either side of a delimiter

%subst is usually paired with %scan, which finds the position to cut at. Test the %scan result for zero first, because a start of zero is an error.

dcl-s fullName varchar(30) inz('Smith, Anna');
dcl-s comma int(10);
dcl-s lastName varchar(30);
dcl-s firstName varchar(30);

comma = %scan(',' : fullName);
if comma > 1;
  lastName = %subst(fullName : 1 : comma - 1);          // 'Smith'
  firstName = %trim(%subst(fullName : comma + 1));      // 'Anna'
endif;

The guard is comma > 1 because a comma at position 1 would give a length of zero for the last name, and a missing comma would give a start of zero. The RPGLE %SCAN and %SCANRPL Reference covers the search side.

Compared with %SCAN, %REPLACE and %LEN

FunctionWhat it doesUse with %subst
%scanFinds a positionSupplies the start or length
%replaceReplaces or inserts text at a position, and returns a new stringUse it when the result should be a new value instead of changing a variable in place
%lenReturns the current lengthKeeps start and length inside the string

Common mistakes

  • Using a %scan result as the start without checking for 0.
  • Asking for more characters than a varying-length field currently holds, even when the maximum is larger.
  • Forgetting that a fixed-length field includes its trailing blanks.
  • Using a literal or an expression as the first argument on the left of an assignment.
  • Giving a length past the end of the target in an assignment.
  • Using %subst to build a longer string. It changes positions inside a variable and does not insert.

FAQ

What happens if I leave out the length?

The part runs from the start position to the end of the string.

Can I change part of a string with %SUBST?

Yes. Put %subst on the left of an assignment, as in %subst(a : 3 : 4) = '****'. The first argument must be a variable.

Does %SUBST change the original string?

Used for its value, no. It returns a new value. Used on the left of an assignment, it changes the variable you name.

Summary

  • %subst(string : start {: length}) returns a part of a string, and with a length of zero it returns an empty string.
  • start must be at least 1, and the part must lie inside the string. For a varying-length field that means inside its current length.
  • On the left of an assignment, it changes only the positions you name, and the first argument must be a variable.
  • The family overview is the RPGLE String BIFs Reference, and the search companion is the RPGLE %SCAN and %SCANRPL Reference.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top