数据结构:为什么%subst不工作

时间:2018-02-28 10:22:44

标签: rpgle

拥有以下数据结构: -

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                                  

定义以下字段: -

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

但是当我做以下操作时: -

 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...

期待accountCode值为x'0031

为什么是x'0000'

注意:我使用双字节。

的问候,
Jemrug

1 个答案:

答案 0 :(得分:2)

没有转换,因为Afthf071不是UCS2值,它是长度为13的字符。如果您要尝试提取两个字节,并将它们复制到accountCode

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

你仍然得到同样的东西,因为这些字节中的值是x'0031',它在x'00000091'中等同(并转换为)UCS2但只有第一个'字符& #39;被复制到accountCode。因此,帐户代码仍为x'0000'

所以外卖是因为你知道你在EBCDIC字符串中嵌入了一些UCS2值,它并不意味着%substr()知道它们在那里。它将整个字符串视为具有相同的CCSID

不确定为什么你要尝试将那个东西子串起来,因为你可以:

accountCode = csactc;

一切都会正确。

在此处将Afthf071转换为所有UCS2时请注意:

ABPOSTCODE = %subst(AfThf071:1);

您仍会遇到%subst()对嵌入式UCS2字符不了解的相同问题,您会得到:

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

因为它将该字符串视为具有作业CCSID的CHAR。在那里(在第二行)看到x'00000091',即CCSID 37 x'0031'的等价物。

不幸的是,没有办法将值转换为适当的CCSID,而不是将其放入具有适当字段类型的数据结构中,如下所示:

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

但是它更容易,因为您已经在数据结构中使用了字段csactc来使用它。如果您真正的问题是您希望ABPOSTCODE全部为UCS2,包括数据结构中的UCS2个字节,那么您只需将其子串起来就像这样:

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

这将转换非UCS2的部分,并保留已经UCS2的部分。现在你有:

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