Skip to main content
  • Converting a CLLE *DEC to a Message Data *DEC on IBM i

    When creating messages in message files, a substitution variable of type *DEC can be used. However, it is not trivial to work with these types in CLLE programs.

    The code snippet on the left shows how a decimal variable in CL can be transformed to the *DEC counterpart in message fields.

    The message data expects a packed field. However, the message data field itself can also contain other fields like object name and other character fields. So how do we get a packed field into a character field in CL?

    You will find that there is no way to convert a decimal CL field into a character field. All conversions like %DEC, %CHAR end up formatting the field in an unusable format for our purpose.

    The trick is to map the CL decimal to a character field.

       dcl        &clDec *dec (5 0) value(0)
       dcl        &msgDec *char stg(*defined) len(3) defvar(&clDec)

    The packed decimal field only uses 3 bytes of memory. Consider the value 12345. For a decimal CL field, this is stored in memory like this:

    byte1 byte2 byte3
    12      34     5F

    The last half byte is F (1111) for positive and D (1101) for negative values.*

    This is the reason why the &msgDec field is 3 bytes. By redefining the storage (memory location) of the &clDec var, we have two variables that point to the same memory location. By changing &clDec, e.g., by passing it as a parameter to an RPG program, the &msgDec is modified by (re)definition. This value of &msgDec is exactly what the message expects.

    Finally, I know how to work with correctly formatted numbers in messages.

    Cheers, Wim

    * Decimal field lengths should preferably be uneven. It is not the half-byte memory waste I'm worried about but the programming ethics.

       pgm
         dcl        &clDec *dec (5 0) value(0)
         dcl        &msgDec *char stg(*defined) len(3) defvar(&clDec)
         dcl        &msgDta *char 100
         dltmsgf    qtemp/msgf
         monmsg     cpf0000
         crtmsgf    qtemp/msgf
         ADDMSGD    MSG0001 MSGF(QTEMP/MSGF) MSG('&1 &2') FMT((*char 6) (*DEC 5))
         chgvar     %sst(&msgdta 1 6) 'Number'
         chgvar     %sst(&msgdta 7 3) &msgDec
         SNDPGMMSG  MSGID(MSG0001) MSGF(QTEMP/MSGF) MSGDTA(&msgDta) TOPGMQ(*EXT)
         chgvar     &clDec 100
         chgvar     %sst(&msgdta 7 3) &msgDec
         SNDPGMMSG  MSGID(MSG0001) MSGF(QTEMP/MSGF) MSGDTA(&msgDta) TOPGMQ(*EXT)
         chgvar     &clDec 1234
         chgvar     %sst(&msgdta 7 3) &msgDec
         SNDPGMMSG  MSGID(MSG0001) MSGF(QTEMP/MSGF) MSGDTA(&msgDta) TOPGMQ(*EXT)
       endpgm                                                        

    Add new comment

    Plain text

    • No HTML tags allowed.
    • Web page addresses and email addresses turn into links automatically.
    • Lines and paragraphs break automatically.
Subscribe to AS400 ibmi clle