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 🙂
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.
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);
IBM i Software Developer, Digital Dad, AS400 Anarchist, RPG Modernizer, Alpha Nerd 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 in the words of the most interesting man in the world: Stay thirsty my friend.
Copying iSeries fields from numeric to Alpha – aka using SQL to change column data type
left adjust alpha into numeric using RPG language
Going the (Levenshtein) Distance in RPG Free
Don’t hardcode library names in your TURNOVER SQL source #youbigsilly
How to Install IBM Access Client Solutions (ACS)
5733XJ1 IBM i Access Client Solutions – QuickStartGuide
Install LANSA AXES – Automatic Web Interface for IBM i (AS/400) 5250 Applications
IFS File system error occurred. Error number 3021?
IBM i Data Obfuscation – Making Data Foggy Murky and Squinty