I need to create an AS/400 command. This command has a parameter with decimal type, which is used to return a value to a CL variable from its command processing program, which is a RPGLE program. Originally the length of the return decimal value should have length 10 with 0 decimal place, which was straightforward to do, as the length of the CL variable is also fixed. Now my boss wanted to enhance this command so that this parameter could return value to a CL variable which has a varying length (still 0 decimal place), similar to what RTVDTAARA command can do when retrieving value from a decimal data area. Can anyone tell me how to make this work? Thanks a lot.
Share
A more complex way to do this is to make a parameter of type *X. Then you can pass any kind of variable to your RPGLE program and process it. You can accept *CHAR, *DEC, *INT, whatever. Here is an example PARM statement for a command definition:
If you enter this and click on help, it can explain how the TYPE(*X) works with the LEN attribute and how the VARY and PASSATR attributes work. For this example, I put in a default of 10,0 for decimals, but it doesn’t have to be.
Then, in your RPGLE program, take that entry parameter and break it up into a Data Structure like this:
You would set that EntryValue to whatever length you feel would be the maximum keeping in mind that decimal variables in CL are stored in packed format in memory, so a 15-byte decimal field would be 8 bytes long (7.5 bytes + .5 byte sign). The data structure breakdown of the fields is as follows:
Then you process your code to retrieve a value and place it in the EntryValue part of the data structure. Be very careful when you update the EntryValue. Any data beyond the length passed does not belong to your program and if you change it, you could break something else in the job. Again, remember that CL decimal variables are stored in memory in the packed decimal format.
To populate a decimal value into an unknown sized packed field, you can do it one of two ways. The easy but tedious way to do it is to create 15 different packed decimal variables and define them in the entry parameter data structure using SELECT and WHEN to populate. The other way is to use pointers and looping. I’ll show you how. To start with, you’ll need some pointers and work fields defined:
What you will do is move the result value into the workDec field. I suggest creating a temporary integer field (5i 0) and multiply the result by 10 to the power of the number of decimal positions in the result to get a whole number with an implied decimal and then EVAL the temporary integer field into workDec. workDec is defined as 15,0 since that’s all the bigger a CL decimal field can be–keeping in mind that we are ignoring decimals at this point. So we know workDec will always be larger, or as large as the passed parameter.
After workDec is set, you start backwards from the rightmost part of both workDec and parmValue dropping the bytes in as you go. We do this because packed decimal values are stored right-justified in memory.