I’m in the final stages of a fun project writing web-services to interface INFOR System21 (on an IBM i aka AS400) with ACSIS Visitrack (on Windows Server), we are consuming (receiving) and serving (sending) all data in a standard alphameric layout But… as any RPG programmer will know… the conversion between alpha to numeric is easy to overlook and can quickly bite you in the arse. So, scratching my head, I’m looking at doing some “RPGLE Converting Character to Numeric” but with no guarantee that the character data actually contains numbers. #clenchesbuttocks
This morning, I had a long discussion with one of the technical analysts talking about the differences in data layout between the “web” world and the “IBM i” world. Out there in website land data flows around in nice alphabetical chunks. I mean, my name is simply “Nick” and the number sixty seven is simply “67” and two and a half is simply “2.5”. But in the database world character can be fixed length “Nick ” or varying length “Nick%” and numerics are commonly stored as packed decimal data so 67 could be stored in a field that is 15,5p so would look like “000000000000067000”. It sounds complicated but if we keep our code clean its a simple process to switch between these formats.
UPDATE: Sridhar Maheswar – Systems Analyst of Extraordinariness – I promised to write a blog about this to make it clear… here it is 🙂
Converting character to numerics
Ironically, in the old OPM (Original Programming Model) RPG layout we simply used a MOVE statement to overlay the data in both character and decimal fields. Simples…
Now using ILE (Integrated language Environment) in RPGLE we just need to know the destination format for our character conversion. In RPGLE we have a nice little %bif (Built in Function) called %DEC that does the decimal conversion for us.
Decimal to Alpha – Solution
Lets say we have an internal numeric field which is 15 long with 5 decimal positions:
D LineAmount S 15P 5
And lets take an input that is upto 20 characters in alpha format:
D WSDLAmount S 20A Inz('12,567.55')
To load this value into the correct format in LineAmont as long as we know the size of field(lineamount) we could say:
LineAmount = %Dec( WSDLAmount : 15 : 5);
The only problem with the previous technique is that we have to say the size of the field…. and…. that’s just not nice is it?
So, lets make it a programming variable and we have a much better solution. The Code could look like this:
LineAmount = %Dec( WSDLAmount : %len(LineAmount) : %decpos(LineAmount));
I like it! But, at time of writing this is just a dream. Sadly, the length and decimal-position parameters must be ‘constants’ so this code will not work. (still maybe someone from IBM is reading this and wants to add something to the next technology reliease?)
Note: We could get around this limitation by by defining a constant value – that contains the length and decimal-positions something like this:
D FieldLength C
D FieldDecimal C
LineAmount = %Dec( WSDLAmount : FieldLength : FieldDecimal);