It has been several been several months since I last wrote a post about CL programming, therefore, I thought it would be a good excuse to share something I was using in a CL program I wrote a couple or so weeks ago. I am sure many have used the Check, %CHECK, and the Check reverse, %CHECKR build in functions, BiFs, in RPG to check a character string for the first place a certain character(s) is not. In the CL program I was writing I needed the same functionality.
IBM has been adding BiFs to CL that are similar to the ones to be found in RPG. Fortunately there are %CHECK and %CHECKR BiFs in CL too. The general format of them is similar to the RPG equivalent:
%CHECK(<test values> <variable> <starting position>) %CHECKR(<test values> <variable> <starting position>) |
I found I could use these BiFs in my CL in two ways:
- Return the first position in the string where a character is not in the test values.
- Send a message to inform the user that the string contains an invalid character.
Let me jump into examples.
01 PGM 02 DCL VAR(&POS) TYPE(*UINT) LEN(2) 03 DCL VAR(&POS2) TYPE(*UINT) LEN(4) 04 DCL VAR(&VALUES1) TYPE(*CHAR) LEN(10) VALUE('0123456789') 05 DCL VAR(&VALUES2) TYPE(*CHAR) LEN(11) VALUE('0123456789 ') 06 DCL VAR(&VAR1) TYPE(*CHAR) LEN(15) |
I wanted to show the variable declarations to explain what they are before I start showing the BiF examples.
Lines 2 and 3: If you have not seen the *UINT data type it defines the variable as an unsigned integer decimal variable.
Lines 3 and 4: This are the test values I will be using with the BiFs. They are different sizes as &VALUES2 contains the numbers 0 – 9 and the value blank, while &VALUE1 just contains 0 - 9. We will see later what difference this makes.
First example:
07 CHGVAR VAR(&VAR1) VALUE('123-456-789') 08 CHGVAR VAR(&POS) VALUE(%CHECK(&VALUES1 &VAR1)) |
After these two lines have executed the variable &POS will contain 4, as the hyphen is not in the list of values in &VALUES1.
I can modify this to return a message to the user:
09 IF COND(%CHECK(&VALUES1 &VAR1) *NE 0) + THEN(SNDPGMMSG MSG('Invalid character in string 1')) 10 ELSE CMD(SNDPGMMSG MSG('Characters in string 1 are valid')) |
In this scenario as &VAR contains a character that is not in &VALUES, therefore, line 9 is executed and the message "Invalid character in string 1" is sent to the program message queue.
This next example shows the difference between using &VALUES1 and &VALUES2.
11 CHGVAR VAR(&VAR1) VALUE('123456789') 12 CHGVAR VAR(&POS) VALUE(%CHECK(&VALUES1 &VAR1)) 13 CHGVAR VAR(&VAR1) VALUE('123456789') 14 CHGVAR VAR(&POS) VALUE(%CHECK(&VALUES2 &VAR1)) |
After line 12 is executed &POS = 10. Variable &VAR is 15 long, therefore, after the values 1 - 9 there are blanks. Blank is not in the list of values in &VALUES1.
After line 14 is executed &POS = 0, as blank is in the list of values in &VALUES2.
This is something to be mindful of when using these BiFs in both CL and RPG.
15 CHGVAR VAR(&VAR1) VALUE('X123456789') 16 CHGVAR VAR(&POS) VALUE(%CHECK(&VALUES2 &VAR1 2)) |
In this example &POS = 0, as the Check starts in the second position of the string which is after the "X" in the first position.
In all the previous examples I have used a variable to contain the list of test values. I can just as well put code the allowed values into the statement like:
17 CHGVAR VAR(&VAR1) VALUE('A B C D E F') 18 CHGVAR VAR(&POS) VALUE(%CHECK('ABCDEF' &VAR1)) 19 CHGVAR VAR(&POS) VALUE(%CHECKR(' ' &VAR1)) |
Line 18: &POS = 2 as that is the first place that the character in the string does not contain one of the values in the test values.
Line 19: As this is a Check reverse &POS = 11 as this is the first position, checking in reverse, that does not contain a blank.
I can use the %CHECKR to determine the length of the string:
20 IF COND(%CHECKR(' ' &VAR1) *LT 11) + THEN(SNDPGMMSG MSG('Character string is too short')) 21 ELSE CMD(SNDPGMMSG MSG('Character string is just right')) |
In this case the message "Character string is just right" is sent to the program message queue as the first non-blank character is in the 11th position of &VAR1.
One thing the CL versions of %CHECK and %CHECKR, that the RPG equivalents cannot, is to directly check the Local Data Area:
22 CHGDTAARA DTAARA(*LDA (500 3)) VALUE('ABC') 23 CHGVAR VAR(&POS2) VALUE(%CHECK(' ' *LDA)) 24 CHGVAR VAR(&POS2) VALUE(%CHECKR(' ' *LDA)) |
Line 23: &POS = 500.
Line 24: &POS = 502.
In my CL program I used these BiFs to determine the length of a string in a screen variable to determine if it was too short for the program's specifications.
You can learn more about this from the IBM website:
This article was written for IBM i 7.3, and should work for some earlier releases too.
No comments:
Post a Comment
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.