Pages

Wednesday, December 7, 2022

New concatenation BiF added to RPG

The fall Technology Refreshes, IBM i 7.5 TR1 and 7.4 TR7, made available on Friday. The folks at RZKH have loaded the necessary PTFs to the server I use, now I can start playing with what became available.

Looking at the documentation for RPG I found a couple of new Built in Functions, BiF, to do with concatenation. In this post I am going to give examples of the %CONCAT BiF.

In the past if I wanted to concatenate a number of variables together into a string I would need to do something like:

String = Var1 + ',' + Var2 + ',' + Var3 ;

Contenating three variables, like the above example, it not a big deal. Imagine what it would be like with ten or twenty variables, very long winded.

The new %CONCAT BiF allows me to give the separator character and then the list the variables or stings to concatenate. The simple syntax is:

Result = %concat(<separator character(s)> : 
                 <string or variable> : 
                 <string or variable> : 
                 <string or variable> ... ) ;

There are two special values that can be used for the separator value:

  • *NONE:  There is no separation between the string
  • *BLANK or *BLANKS:  The separator character will be blank

Onto the first example using the *NONE as the separator character.

01  **free
02  dcl-s String char(52) ;

03  String = %concat(*none : 'ANT' : 'BEAR' : 'CAT' : 'DOG' : 'EEL') ;
04  dsply String ;

Line 1: My RPG code is always 100% totally free format.

Line 2: This is the definition for the variable the results of the various concatenations. It is 52 characters long as that is the largest size allowed by the DSPLY operation code.

Line 3: This is the %CONCAT statement in action. The result of the concatenation will be in the variable String. I am using *NONE as the separator.

line 4: I am displaying the contents of String with the display operation code.

The result is:

DSPLY  ANTBEARCATDOGEEL

I can replace the *NONE with a null value as shown below.

05  String = %concat('' : 'ANT' : 'BEAR' : 'CAT' : 'DOG' : 'EEL') ;
06  dsply String ;

Line 5: The only difference between Line 3 and this line is that I have defined null as the separator. I have defined null as two apostrophes ( ' ) next to each other with no value between.

The result is the same as the previous statement.

DSPLY  ANTBEARCATDOGEEL

You have to agree that the above results are not readable. I need some kind of a separator between part of the string.

07  String = %concat(';' : 'ANT' : 'BEAR' : 'CAT' : 'DOG' : 'EEL') ;
08  dsply String ;

Line 7: I am using the semicolon ( ; ) as the separator.

The result is:

DSPLY  ANT;BEAR;CAT;DOG;EEL

Here I am using two separator characters, comma and a space.

09  String = %concat(', ' : 'ANT' : 'BEAR' : 'CAT' : 'DOG' : 'EEL') ;
10  dsply String ;

IMHO this result is most readable.

DSPLY  ANT, BEAR, CAT, DOG, EEL

Using strings is not really something I would do in real life. In the real world I would be concatenating variables or something similar. In this example I wanted to see if %CONCAT would allow me to use subfields from a data structure.

11  dcl-s Separator char(1) inz('-') ;

12  dcl-ds Example qualified ;
13    SF1 char(10) inz('Apple') ;
14    SF2 char(10) inz('BERRY') ;
15    SF3 char(10) inz('cantaloupe') ;
16    SF4 char(10) inz('Donut') ;
17    SF5 char(10) inz('Egg') ;
18  end-ds ;


19  String = %concat(Separator : Example.SF1 : Example.SF2 :
                     Example.SF3 : Example.SF4 : Example.SF5) ;
20  dsply String ;

Line 11: I have defined the separator character in a variable.

Line 12 – 18: This is the definition of the data structure. It has five subfields that are all have fixed character length of 10.

Line 19: Everything in the %CONCAT is a variable or data structure subfield.

The result is:

DSPLY  Apple     -BERRY     -cantaloupe-Donut     -Egg

Why the spaces between the values? As I defined the data structure subfields as character 10 there will be spaces as each subfield is 10 long.

To improve the above example, and give a better result:

21  String = %concat(Separator :
                     %trimr(Example.SF1) :
                     %trimr(Example.SF2) :
                     %trimr(Example.SF3) :
                     %trimr(Example.SF4) :
                     %trimr(Example.SF5)) ;
22  dsply String ;

Line 21: I have used the %TRIMR BiF to remove the trailing spaces from the data structure subfields.

The result looks a lot more what I wanted:

DSPLY  Apple-BERRY-cantaloupe-Donut-Egg

These days I define the character variables in my RPG source as variable length, VARCHAR, this removes the need for me to trim them when doing things like this. Here is an example of what I could do with variable character variables:

23  dcl-s Var1 varchar(10) inz('Zebra') ;
24  dcl-s Var2 like(Var1) inz('Yak') ;
25  dcl-s Var3 like(Var1) inz('Xerus') ;

06  String = %concat('.' : Var1 : Var2 : Var3) ;
07  dsply String ;

The result is what I wanted without the need to trim anything.

DSPLY  Zebra.Yak.Xerus

I can say that this is something I will be using as it is a neat and tidy method to concatenate things together.

There is another concatenation BiF this time for arrays.

 

You can learn more about the RPG %CONCAT BiF from the IBM website here.

 

This article was written for IBM i 7.5 TR1 and 7.4 TR7.

2 comments:

  1. Looks useful. I would vote to have %trimr implicitly applied to each argument. Why does every language have to do string interpolation differently? PHP is the easiest. In a double quoted literal, $variable names are automatically replaced in the string with the variable value.

    ReplyDelete
  2. This would make it very easy to create a json object

    ReplyDelete

To prevent "comment spam" all comments are moderated.
Learn about this website's comments policy here.

Some people have reported that they cannot post a comment using certain computers and browsers. If this is you feel free to use the Contact Form to send me the comment and I will post it for you, please include the title of the post so I know which one to post the comment to.