.st0{fill:#FFFFFF;}

Cleaning up a string of comma separated account numbers in RPGLE 

 May 16, 2019

By  NickLitten

I was emailed a little IBM i programming question this morning:

An input parameter @Account is a 100 character string for one to
x number of 8 digit accounts separated with a comma (,). Each
account can be entered with commas between each account.
Example: The string @Account could be “123,00574, 12,142 ā€¦ “.
Spaces will be converted to zeros, such as “000012”.
The conversion internal in this program will convert this string
as “00000123,00000574,00000012,00000142 ā€¦ “.

Mike

So, I grabbed a coffee, finished my doughnut and wrote this little RPGLE Sub-procedure to take the input string, extract out numbers, neatly format them and return them as a string of 8 character account numbers with leading zeros. hashtag nerdlife.

What is the basic logic?

Let’s write this using an RPGLE array to break each of the account numbers into separate elements, then load each element with only the numbers (1 thru 9) and append a comma as a seperator.

Just for the fun of it, let’s add it as a little sub-procedure to make it easily reusable.

*FREE
ctl-opt copyright('| TEST V001 2019.05.16') debug option(nodebugio:srcstmt)   datfmt(iso-) timfmt(*iso.) indent('| ');

dcl-pi *n;
  parm Char(100);
end-pi;

// send the input parameter to our number conversion procedure
parm = convert_numbers (parm);

// end neatly - the new formatted value of "PARM" will be returned
*inlr = *on;


// +------------------------------------------------------------------------------+
// | convert_numbers                                                              |
// |  The input parameter @Account is a 100 character string for one to           |
// |  x number of 8 digit accounts separated with a comma (,).  Each              |
// |  account can be entered with commas between each account.                    |
// |  Example: The string @Account could be "123,00574,   12,142             ".  |
// |  Spaces will be converted to zeros, such as "000012".                        |
// |  The conversion internal in this program will convert this string            |
// |  as "00000123,00000574,00000012,00000142                              ".    |
// +------------------------------------------------------------------------------+
dcl-proc convert_numbers export;
   dcl-pi convert_numbers char(100);
     proc_input Char(100) const;
   end-pi;
 
   dcl-s posn int(10);  // count through the 100 positions of the input
   dcl-s element int(10);  // count the elements as we fill them
   dcl-s rtnval char(100);  // final cleaned up value
   dcl-s numbers char(10) Inz('0123456789');
   dcl-ds oneHundredCharacters;
     char char(10) dim(100);
   end-ds;

 monitor;

 // Read through the variable and extrapolate int numeric 8char elements

 element = 1;
 rtnval = proc_input;

 for posn = 1 to %size(proc_input);

 //increment to next element when we find a field delimiter ','   
 // or its the final position

 if %subst(rtnval:posn:1) = ',' or posn = %size(proc_input);

   if char(element) <> *blanks;
     // right adjust and append a seperator[,]
     evalr char(element) = %trimr(char(element)) + ',';
     // replacing blanks with ZERO
     char(element) = %ScanRpl(' ' : '0' : char(element));
     //move to next element for the rest of the loop
     element += 1;
     endif;

  // store this character in the next position of the current element
  // %check - First position in the searched-data that contains a
  //   character not in the list of the characters in the compare value.
  elseif %check(numbers:%subst(rtnval:posn:1)) = 0;
    char(element) = %trim(char(element)) + %subst(rtnval:posn:1);
  endif;
 endfor;

 rtnval = oneHundredCharacters;

 on-error;
     rtnval = '* Conversion Failed';
   endmon;
 return rtnval;
 end-proc;

PS: Before leaving any abusive “ahh your code is crappy it could be much smaller” just remember… I will resort to the defense of “I tried to keep the code snippet as simple and readable as possible” šŸ™‚ #lotsofwaystoskinanrpgcat

Testing the RPG Code

Cleaning up a string of comma separated account numbers in RPGLE 1
CALL PGM(TEST)                                               
      PARM(' PLOP1,      22,     333,    4444,   55555,  66 
           6666,  77!7777,  888888, 9e43299,,|,1234ABC')      

Note some deliberately DUFF non-numeric characters!

Once the sub-procedure has tinkered with it – these values are returned:

  ....5...10...15...20...25...30...35...40...45...50...55...60 
1   '000000001,000000022,000000333,000004444,000055555,000666666,'
61   '000777777,000888888,000943299,000001234,'                    
Cleaning up a string of comma separated account numbers in RPGLE 2

Hope it works for you Mike! šŸ™‚

NickLitten


IBM i Software Developer, Digital Dad, AS400 Anarchist, RPG Modernizer, Shameless Trekkie, Belligerent Nerd, Englishman Abroad and Passionate Eater of Cheese and Biscuits. Nick Litten Dot Com is a mixture of blog posts that can be sometimes serious, frequently playful and probably down-right pointless all in the space of a day. Enjoy your stay, feel free to comment and remember: If at first you don't succeed then skydiving probably isn't a hobby you should look into.

Nick Litten

related posts:

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}
__CONFIG_colors_palette__{"active_palette":0,"config":{"colors":{"cff50":{"name":"Main Accent","parent":-1},"a344d":{"name":"Accent Transparent","parent":"cff50"}},"gradients":[]},"palettes":[{"name":"Default","value":{"colors":{"cff50":{"val":"var(--tcb-skin-color-0)"},"a344d":{"val":"rgba(46, 138, 229, 0.85)","hsl_parent_dependency":{"h":210,"l":0.54,"s":0.78}}},"gradients":[]},"original":{"colors":{"cff50":{"val":"rgb(0, 178, 255)","hsl":{"h":198,"s":1,"l":0.5}},"a344d":{"val":"rgba(0, 178, 255, 0.85)","hsl_parent_dependency":{"h":198,"s":1,"l":0.5}}},"gradients":[]}}]}__CONFIG_colors_palette__

Get In Touch

Iā€™m always looking for awesome input, feedback and critique!

>