jemrug
jemrug

Reputation: 89

Data structures: Why does %subst not working

Have the following data structure:-

D Afthf071      E DS                  ExtName(thf071)                
 *-------------------------------------------------------------------
 * Data structure . . . . . . :  AFTHF071                            
 * External format  . . . . . :  TH071 : T0TU0TDDR/THF071            
 * Format text  . . . . . . . :  Customer Address Master File        
 *-------------------------------------------------------------------
D CSSTCN                         1S 0                                
D CSBRNN                        10S 0                                
D CSACTC                         1C                                  

Have the following fields defined:-

D ABPOSTCODE      S            100c    
D accountCode     S              1c    
D w_cuno          S             10s 0  

But when I do the following operation :-

 if %found(THf071a);                   
   clear ABPOSTCODE;                   
   ABPOSTCODE = %subst(AfThf071:1);    
   accountCode= %subst(AfThf071:12:1); 
 endif;   
 return;  
/end-free 

 Debug values:-
 EVAL AfThf071                    
 CSSTCN OF AFTHF071 = 0.          
 CSBRNN OF AFTHF071 = 0000000006. 
 CSACTC OF AFTHF071 = 1           

 EVAL AfThf071:x                                                      
  00000     F0F0F0F0 F0F0F0F0 F0F0F600 310030F0   - 00000000006....0
  00010     F0F0F0F0 F0F0F0F0 F0F3F9F0 F0F0F000   - 000000000390000.

EVAL accountCode:x  
 00000     0000...

was expecting accountCode value to be x'0031.

why is it x'0000' ?

Note: I'm using double byte.

Regards,
Jemrug

Upvotes: 1

Views: 643

Answers (1)

jmarkmurphy
jmarkmurphy

Reputation: 11493

No conversion happens because Afthf071 is not a UCS2 value, it is a Char with length 13. If you were to try to pull out both bytes, and copy them to accountCode

accountCode = %subst(Afthf071: 12: 2);

You still get the same thing because the value in those bytes is x'0031' which is equivalent (and converted to) to x'00000091' in UCS2 but only the first 'character' is copied to accountCode. So account code is still x'0000'.

So the takeaway is that just because you know you have some UCS2 values embedded in an EBCDIC string, it doesn't mean that %substr() knows they are there. It treats the whole string as if it has the same CCSID.

Not real sure why you are trying to substring that thing anyway since you could just:

accountCode = csactc;

and everything would be correct.

Note when you convert Afthf071 to all UCS2 here:

ABPOSTCODE = %subst(AfThf071:1);

You will still have the same issue that %subst() doesn't know about the embedded UCS2 characters, and you get:

00300030 00300030 00300030 00300030
00300030 00300000 00910020 00200020
00200020 00200020 00200020 00200020
... to the end of the field

Because it is treating that string as a CHAR with the job CCSID. See that x'00000091' in there (on the second line), that is the Unicode equivalent of CCSID 37 x'0031'.

Unfortunately there is no way to cast a value to the appropriate CCSID other than to drop it into a data structure with an appropriate field type like this:

dcl-ds struct;
  ucs2field     Ucs2(1);
end-ds;
struct = %subst(AfThf071: 12: 1);
accountCode = ucs2Field;

But then it is just easier, since you already have the field csactc in a data structure to just use that. If your real problem is that you want ABPOSTCODE to be all UCS2 including the UCS2 bytes in the data structure, you are just going to have to substring it out like this:

ABPOSTCODE = %ucs2(%subst(AfThf071: 1: 11)) + CSACTC;

This will convert the portions that are not UCS2 and leave the portions that are already UCS2 alone. Now you have:

00300030 00300030 00300030 00300030
00300030 00300031 00200020 00200020
00200020 00200020 00200020 00200020
... to the end of the field

Upvotes: 2

Related Questions