New in V7R5 – Part 1. %LIST, %RANGE, WHEN-IS, WHEN-IN

Hello everyone and welcome to this new series in which I am going to write about all the new operating codes and enhancements to ILE RPG that were introduced with IBM i’s V7R5 and subsequent TRs, including the one that has just become available for download, TR3.

In this first part of the series I am going to write about one of the enhancements  that I liked the most, which is the possibility to use an operand in the SELECT statement and then check its value using WHEN-IN or WHEN-IS. Since WHEN-IN supports the built-in functions %LIST and %RANGE they will also be discussed here so that the code is completely clear. 

%LIST

%LIST (item { : item { : item … } } )

It returns an array with the elements passed as parameter. It can be used in any expression where an array can be used except SORTA, %ELEM, %LOOKUP and %SUBARRAY.

%LIST Example:

				
					**free

ctl-opt dftactgrp(*no) main(main);

dcl-s fruits   varchar(15) dim(5);
dcl-s fruit    varchar(15);
dcl-s numFruit packed(1);
dcl-s color    varchar(10) inz('Red');

dcl-proc main;
    dcl-pi *n extpgm('LIST') end-pi;

    fruits = %list('Apple':'Pear':'Orange':'Kiwi':'Melon');
    clear numFruit;
    for-each fruit in fruits;
        numFruit += 1;
        snd-msg 'Fruit number ' + %char(numFruit) + ' is ' + fruit;
    endfor;

    if color in %list('Blue':'Green':'Yellow':'Red');
        snd-msg 'Color válido';
    endif;

    snd-msg 'Program LIST ended. Run DSPJOBLOG command to see the result.' %target(*self:2);

    return;
end-proc;
				
			

Explanation:

Line 1: Code will be fully free.

Line 3: This is a non-cycle program.

Line 5: Array variable to hold the result of %LIST built-in function.

Line 6: Variable to be used with the for-each op code.

Line 7: Variable to hold the number of the fruit in the array.

Line 8: Variable to compare with the result of the built-in function %LIST.

Line 10: Begin of main procedure.

Line11: Procedure interface.

Line 13: Built-in function %LIST converts the parameter values in an array and then the result is assigned to fruit array.

Line 14: As it is a non-cyclic program we must clean the content of the variable in case we want to run the program again so that it has its initial value of zero.

Lines 15-18: for-each loop to print the content of the array in the job log. 

Lines 20-22: Check if the value of the variable color is int the array returned by %LIST built-in function.

Line 24: A message is sent to the message line of the screen so the user can see where to look for the messages.

When the program is run the a message appears at the message line of the screen.

Then looking at the job log the other messages are shown.

%RANGE

%RANGE (lower-limit : upper-limit)

It returns no value and can only be specified with the IN operator. The first operand of the IN operator cannot be an array. The data types must be comparable.

%RANGE Example:

				
					**free

ctl-opt dftactgrp(*no) main(main);

dcl-s num    packed(3) inz(25);
dcl-s letter char(1) inz('f');

dcl-proc main;
    dcl-pi *n extpgm('RANGE') end-pi;

    if num in %range(20:50);
        snd-msg 'Number ' + %char(num) + ' is in the range.';
    endif;

    if %upper(letter) in %range('C':'K');
        snd-msg 'Letter ' + letter + ' is in the range.';
    endif;

    snd-msg 'Program RANGE ended. Run DSPJOBLOG command to see the result.' %target(*self:2);

    return;
end-proc;
				
			

Explanation:

Line 1: Code will be fully free.

Line 3: This is a non-cycle program.

Line 5: Variable to hold the num to compare with %RANGE built-in function.

Line 6: Variable to hold the letter to compare with %RANGE.

Line 8: Begin of main procedure.

Line 9: Procedure interface.

Lines 11-13: Check if the value of num is in the range.

Lines 15-17: Check if the value of letter in uppercase is in the range.

Line 19: A message is sent to the message line of the screen so the user can see where to look for the messages.

When the program is run the a message appears at the message line of the screen.

Then looking at the job log the other messages are shown.

WHEN-IS, WHEN-IN

The SELECT opcode now supports an operand and you can check its value with WHEN-IS and WHEN-IN.

  • WHEN-IN accepts %LIST, %RANGE, %SUBARR or an array as a comparison value.
  • WHEN-IS checks whether the value specified in the SELECT operand is equal to the value specified in WHEN-IS.

WHEN-IS, WHEN-IN Example:

				
					**free

ctl-opt dftactgrp(*no) main(main);

dcl-s num1   packed(3) inz(25);
dcl-s num2   packed(3) inz(3);

dcl-proc main;
    dcl-pi *n extpgm('WHENISIN') end-pi;

    select num1;
        when-is primeNum(num1:isPrimeNum(num1));
            snd-msg 'Num1 is a prime num.';
        when-in %list(5:10:15:20:25:30);
            snd-msg 'Num1 is in the list.';
        when-in %range(15:30);
            snd-msg 'Num1 is in the range.';
    endsl;

    if num1 in %range(20:50);
        snd-msg 'Number ' + %char(num1) + ' is in the range. Checked out of SELECT.';
    else;
        snd-msg 'Number ' + %char(num1) + ' is NOT in the range. Checked out of SELECT.';
    endif;

    select num2;
        when-is primeNum(num2:isPrimeNum(num2));
            snd-msg 'Num2 is a prime num.';
        when-in %list(5:10:15:20:25:30);
            snd-msg 'Num2 is in the list.';
        when-in %range(15:30);
            snd-msg 'Num2 is in the range.';
    endsl;

    if num2 in %range(20:50);
        snd-msg 'Number ' + %char(num2) + ' is in the range. Checked out of SELECT.';
    else;
        snd-msg 'Number ' + %char(num2) + ' is NOT in the range. Checked out of SELECT.';
    endif;

    snd-msg 'Program WHENISIN ended. Run DSPJOBLOG command to see the result.' %target(*self:2);

    return;
end-proc;

dcl-proc isPrimeNum;
    dcl-pi *n ind;
        num packed(3);
    end-pi;

    dcl-s i packed(3);
    dcl-s result packed(3);

    for i = (num-1) downto 1;
        result = %rem(num:i);
        if result = 0;
            leave;
        endif;
    endfor;

    return (i = 1);
end-proc;

dcl-proc primeNum;
    dcl-pi *n packed(3);
        num     packed(3);
        isPrime ind const;
    end-pi;

    if isPrime;
        return num;
    endif;

    return num + 1;
end-proc;
				
			

Explanation:

Line 1: Code will be fully free.

Line 3: This is a non-cycle program.

Line 5: Variable to hold num1 which is not a prime number.

Line 6: Variable to hold num2 which is a prime number.

Line 8: Begin of main procedure.

Line 9: Procedure interface.

Lines 11-18: This select has num1 as operand. So the value of num1 will be checked in every when sentence.

First when is when-is and it will check if the value that returns primeNum function is equal to the value that holds num1.

Second when is when-in and it is used to check if the value that holds num1 is in the list of %list built-in function.

Third when is when-in and it is used to check if the value that holds num1 is in the range of %range built-in function.

Lines 20-24: As the first select will execute the second when, this if is here to demonstrate the use of %range when the number is in the range specified.

Lines 26-33:

This select has num2 as operand. So the value of num2 will be checked in every when sentence.

First when is when-is and it will check if the value that returns primeNum function is equal to the value that holds num2.

Second when is when-in and it is used to check if the value that holds num2 is in the list of %list built-in function.

Third when is when-in and it is used to check if the value that holds num2 is in the range of %range built-in function.

Lines 35-39: As this second select will execute the first when, this if is here to demonstrate the use of %range when the number is NOT in the range specified.

Line 41: A message is sent to the message line of the screen so the user can see where to look for the messages.

Lines 46-59: A procedure that returns whether a number is a prime number. It simply calculates the remainder by dividing all numbers less than num until the result is 0 (zero), so it is not a prime number, or 1, so it is a prime number.

Lines 64-75: Since when-is checks whether the value of the select statement’s operand is equal to a value and the types must match, it is required to compare it with a value of the same type, but the isPrimeNum procedure returns an indicator, not a number, so they cannot be compared. This procedure returns the value of num if the number is prime or a different value, num+1, for example, otherwise and in this way the comparison can be made.

When the program is run the a message appears at the message line of the screen.

Then looking at the job log the other messages are shown.

I hope you liked the post. Don’t hesitate to comment what you want and see you in the next post.

Leave a Reply

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