Modify hexa string value in CL

1465 pts.
Tags:
AS/400
CL Program
I have a hexa string and I want to modify some value while running program through CL below is the hexa string.
X'011F011F000000000F099999999FC9020160309FF0D5
404040F9F9F9E3000000000F40404040404040')
In the above string I have a date 20160309. Now I want to change this date to current date.
0

Answer Wiki

Thanks. We'll let you know when a new response is added.
Send me notifications when members answer or reply to this question.

Discuss This Question: 10  Replies

 
There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when members answer or reply to this question.
  • TheRealRaven
    First, why would you ever want to handle that as a hex string? Why not handle it in the normal way? What is your OS version?

    But you'd usually modify it by using the %BIN() builtin CL function. Looking at your hex string, it looks like the complete hex date is actually x'020160309F'. Changing that portion of the string might take some creative coding.
    35,130 pointsBadges:
    report
  • TheRealRaven
    Note that the %BIN() function can only handle lengths of 2 or 4 bytes because it's intended to convert between character or decimal values and binary integers. If you have a new hex string for a new date, e.g., x'020160310F', you can simply insert that into your larger hex string with the %SST() substring CL builtin function. (Even so, it still isn't clear why you'd want to do this as hex.)
    35,130 pointsBadges:
    report
  • 9783444184
    Actually i am sending this string as a parameter in a program my problem is while sending this string with out any changes it's running fine but if i changed the date values is giving decimal data error.
    For example: Executing ok without changesCHGVAR VAR(&MAINPRM) Value(+                            
               X'011F011F000000000F099999999FC9020160309FF0D5+  
               404040F9F9F9E3000000000F40404040404040')         
                                                                
    CALL       PGM(SYSOVRC) PARM('ACP210B' 'X' &MAINPRM) 
    With Change:  CHGVAR     VAR(&MAINPRM) +                                   
                   VALUE('X''011F011F000000000F099999999FC90'||+   
                   &DISO||+                                        
                   'FF0D5404040F9F9F9E3000000000F40404040404040'+  
                   )                                               
                                                                   
    
      CALL       PGM(SYSOVRC) PARM('ACP210B' 'X' &MAINPRM) 
    Where DISO is current date 20160311               
    1,465 pointsBadges:
    report
  • philpl1jb
    So you want &DISCO to be the current date in char as CCYYMMDD
    54,090 pointsBadges:
    report
  • philpl1jb
    This would work 
    Dcl &YYYY *Char 4
    Dcl &Month *Char 2
    Dcl &Day *Char 2
    Dcl &Date *Char 8
    RTVSYSVAL SYSVAL(QYEAR) RTNVAR(&YEAR)
    RTVSYSVAL SYSVAL(QMONTH) RTNVAR(&MONTH)
    RTVSYSVAL SYSVAL(QDAY) RTNVAR(&DAY)
    CHGVAR VAR(&YYYY) VALUE('20' *CAT &YEAR)
    CHGVAR VAR(&DATE) VALUE(&YYYY *CAT +
    &MONTH *CAT &DAY)
    54,090 pointsBadges:
    report
  • TheRealRaven
    What is your OS version? If you're at V5R4 or later, there are much better ways to handle it.
    35,130 pointsBadges:
    report
  • 9783444184
    Thanks for your valuable input 
    My Os version is V7R1,
    I can modifiy my above string and i am getting proper value also in my variable but when i am passing my variable in called program its giving me :
    RPG status 00907 caused procedure ACP210B in program LX835O/ACP210B to stop.
    below is my codePGM                                                                    
             DCL        VAR(&DATE) TYPE(*CHAR) LEN(6)                      
             DCL        VAR(&DISO) TYPE(*CHAR) LEN(8)                      
             DCL        VAR(&MAIN) TYPE(*CHAR) LEN(512)                    
             DCL        VAR(&MAINPRM1) TYPE(*CHAR) LEN(511)                
             DCL        VAR(&MAINPRM2) TYPE(*CHAR) LEN(511)                
             DCL        VAR(&FIRST) TYPE(*CHAR) LEN(10) VALUE(ACP210B)     
             DCL        VAR(&SECOND) TYPE(*CHAR) LEN(1) VALUE(X)           
             MONMSG     MSGID(CPF0000)                                     
             RTVSYSVAL  SYSVAL(QDATE) RTNVAR(&DATE)                        
             CVTDAT     DATE(&DATE) TOVAR(&DISO) FROMFMT(*MDY) +           
                          TOFMT(*YYMD) TOSEP(*NONE)                        
              /* CHGVAR     VAR(&MAIN) Value(+   */                        
              /*        X'011F011F000000000F099999999FC9020160309FF0D5+ */ 
              /*        404040F9F9F9E3000000000F40404040404040')        */ 
                                                                           
             CHGVAR     VAR(&MAIN) +                                       
                          VALUE('X''011F011F000000000F099999999FC90'||+    
                          &DISO||+                                         
                          &DISO||+                                          
                          'FF0D5404040F9F9F9E3000000000F40404040404040')    
                                                                            
             CALL       PGM(SYSOVRC) PARM(&FIRST &SECOND &MAIN)             
                                                                            
    1,465 pointsBadges:
    report
  • TheRealRaven
    Since &DISO is a *CHAR variable and contains normal characters, you can't concatenate it into the middle of a hew string and expect it to convert to the hex representation of a numeric variable.

    The hex representation of a numeric variable is different from the hex representation of a character variable. You would have to convert &DISO to numeric first, then take it as hex.

    I'll try to post a useful code sample later today.
    35,130 pointsBadges:
    report
  • TheRealRaven
    The snippet of code that you posted can be modified to look like this:
    pgm   ( +
          )
    
       dcl   &date        *char     6
       dcl   &diso        *char     8
       dcl   &decDate     *dec  (   9 0 )
    
       dcl   &main        *char   512     Value( +
                  x'011F011F000000000F099999999FC9020160309FF0D5+
                  404040F9F9F9E3000000000F40404040404040' )
       dcl    &m1         *dec  (   3 0 ) stg( *defined ) defvar( &main    1 )
       dcl    &m2         *dec  (   3 0 ) stg( *defined ) defvar( &main    3 )
       dcl    &m3         *dec  (   9 0 ) stg( *defined ) defvar( &main    5 )
       dcl    &m4         *dec  (   9 0 ) stg( *defined ) defvar( &main   10 )
       dcl    &m5         *char     1     stg( *defined ) defvar( &main   15 )
       dcl    &mDate      *dec  (   9 0 ) stg( *defined ) defvar( &main   16 )
       dcl    &m6         *char     5     stg( *defined ) defvar( &main   21 )
       dcl    &m7         *char     3     stg( *defined ) defvar( &main   26 )
       dcl    &m8         *char     1     stg( *defined ) defvar( &main   29 )
       dcl    &m9         *dec  (   9 0 ) stg( *defined ) defvar( &main   30 )
       dcl    &m10        *char     7     stg( *defined ) defvar( &main   35 )
    
       dcl   &mainPrm1    *char   511
       dcl   &mainPrm2    *char   511
    
       dcl   &first       *char    10     value( 'ACP210B' )
       dcl   &second      *char     1     value( 'X' )
    
       monmsg    ( CPF0000 )
    
       rtvsysval   sysval( QDATE ) RTNVAR( &DATE )
    
       cvtdat      date( &DATE ) tovar( &DISO ) fromfmt( *MDY ) +
                     tofmt( *YYMD ) tosep( *NONE )
    
       chgvar            &decDate                 &diso
       chgvar            &mDate                   &decDate
    
    dmpclpgm
    
       /* call        SYSOVRC     ( &first &second &main ) */
    
       return
    
    endpgm
    I made three changes.

    First, I changed the coding style to make it a little easier to read.

    Second, I added PGM and ENDPGM so it can be compiled and executed. And I added DMPCLPGM and turned the CALL into a comment. You can compile and run this to get the memory dump. When you look at the dump, you can see how the &mDate sub-field has been changed to be the hex value of the new date.

    And third, I changed &MAIN to be a data structure with sub-fields defined under it. That's how I can reference the part that has a 9-digit packed decimal date without needing to handle as hex.

    The basic ode is like this:
    pgm   ( +
          )
    
       dcl   &date        *char     6
       dcl   &diso        *char     8
       dcl   &decDate     *dec  (   9 0 )
    
       dcl   &main        *char   512     Value( +
                  x'011F011F000000000F099999999FC9020160309FF0D5+
                  404040F9F9F9E3000000000F40404040404040' )
       dcl    &m1         *dec  (   3 0 ) stg( *defined ) defvar( &main    1 )
       dcl    &m2         *dec  (   3 0 ) stg( *defined ) defvar( &main    3 )
       dcl    &m3         *dec  (   9 0 ) stg( *defined ) defvar( &main    5 )
       dcl    &m4         *dec  (   9 0 ) stg( *defined ) defvar( &main   10 )
       dcl    &m5         *char     1     stg( *defined ) defvar( &main   15 )
       dcl    &mDate      *dec  (   9 0 ) stg( *defined ) defvar( &main   16 )
       dcl    &m6         *char     5     stg( *defined ) defvar( &main   21 )
       dcl    &m7         *char     3     stg( *defined ) defvar( &main   26 )
       dcl    &m8         *char     1     stg( *defined ) defvar( &main   29 )
       dcl    &m9         *dec  (   9 0 ) stg( *defined ) defvar( &main   30 )
       dcl    &m10        *char     7     stg( *defined ) defvar( &main   35 )
    
       dcl   &mainPrm1    *char   511
       dcl   &mainPrm2    *char   511
    
       dcl   &first       *char    10     value( 'ACP210B' )
       dcl   &second      *char     1     value( 'X' )
    
    
       monmsg    ( CPF0000 )
    
    
       rtvsysval   sysval( QDATE ) RTNVAR( &DATE )
    
       cvtdat      date( &DATE ) tovar( &DISO ) fromfmt( *MDY ) +
                     tofmt( *YYMD ) tosep( *NONE )
    
    
       chgvar            &decDate                 &diso      /* Note 1 */
       chgvar            &mDate                   &decDate   /* Note 2 */
    
    
    dmpclpgm
    
    
       /* call        SYSOVRC     ( &first &second &main ) */
    
       return
    
    endpgm
    At (Note 1) I convert the character value in &DISO to a *DEC (9 0) value in &DECDATE.

    At (Note 2) I copy the value from &DECDATE into the data structure su bfield named &MDATE.

    It's not really necessary to do that in two steps. The &DECDATE variable can be dropped, and the &DISO value can convert directly into &MDATE.

    I looked at your hex value and decided to create sub-fields for each area that made sense. In this example code, the only sub-field that is needed is &MDATE. The whole data structure could be defined like this:
       dcl   &main        *char   512     Value( +
                  x'011F011F000000000F099999999FC9020160309FF0D5+
                  404040F9F9F9E3000000000F40404040404040' )
       dcl    &mDate      *dec  (   9 0 ) stg( *defined ) defvar( &main   16 )
    Since the other sub-fields aren't referenced, they don't have to be defined.

    However, they should be defined because they should be referenced. The VALUE() clause should be removed from &MAIN, and the sub-fields should have their values set:
       chgvar            &m1                    ( 11 )
       chgvar            &m2                    ( 11 )
       chgvar            &m3                    ( 0 )
       chgvar            &m4                    ( 99999999 )
       chgvar            &m5                      'I'
    
       chgvar            &decDate                 &diso      /* Note 1 */
       chgvar            &mDate                   &decDate   /* Note 2 */
    
       chgvar            &m6                      '0N   '
       chgvar            &m7                      '999'
       chgvar            &m8                      'U'
       chgvar            &m9                    ( 0 )
       chgvar            &m10                     '       '
    It looks like &M6 is probably really supposed to be two or maybe three sub-fields instead of only one, but the values will be set the same either way.

    Anyway, by using STG( *DEFINED ) and DEFVAR(), you can declare sub-fields with proper data types. That way you avoid the complicated hex values. You can assign values normally and make maintenance much easier.

    35,130 pointsBadges:
    report
  • 9783444184
    Thanks TheRealRaven ,
    I have resolved my problem but you given me a good solution better then me.
    I have resolved my problem but you have given me a good ,
    1,465 pointsBadges:
    report

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

To follow this tag...

There was an error processing your information. Please try again later.

Thanks! We'll email you when relevant content is added and updated.

Following

Share this item with your network: