SAP ABAP转换特殊字符乱码

1 篇文章 0 订阅

问题的起因是通过txt使用ABAP向SAP导数时,某些文字会转换为乱码。

嫌长不看版:codepage使用8402

有问题的文字为下表中未画删除线的文字:

GBK举例表 来自:GBK编码
FE 0 1 2 3 4 5 6 7 8 9 A B C D E F
4 兀 嗀 﨎 﨏 﨑 﨓 﨔 礼 﨟 蘒 﨡 﨣 﨤 﨧 﨨 﨩
5                
6                
7               
8                
9                
A                

GBK的基本姿势

首先GBK是对GB2312的扩展,采用双字节表示,总体编码范围为 8140-FEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间,除去所有7F结尾的编码(xx7F,如上图中FE7F)。
上图左上角的”FE”指的该表格中的文字的编码都是以”FE”开头,第三位要看左边的数字,第四位要看上面的数字,例如“兀”的编码为”FE40”,“”的编码为”FE50”。

GBK的全部编码分为三大部分:
1. 汉字区。
2. 图形符号区。
3. 用户自定义区。
每个部分具体包括哪些请看GBK编码,写的非常清楚。在这里只需要说一下,用户自定义区的范围是:
(1) AAA1-AFFE,码位 564 个。
(2) F8A1-FEFE,码位 658 个。
(3) A140-A7A0,码位 672 个。

GBK编码范围表:wiki-GBK
GBK编码范围表

SAP端的基本姿势

1.WebDynpro中的上传特点

WebDynpro中使用FileUpload控件进行文件的上传,控件的data属性要绑定给一个xstring类型的Attribute(具体如何实现附件上传本文不具体论述)。我们可以读取这个Attribute值,来查看文件传到SAP后端之后的情况。
现在我们先新建一个文本文档,里面只写一个字:“﨩”,没有回车。然后通过WebDynpro的FileUpload控件上传此文件,可以看到后端获取到的值为:”FE4F”。
debug查看上传控件的data属性
我们再查看前面的GBK举例表,在GBK编码中“﨩”的编码也是“FE4F”,这代表着SAP把txt文档的内容直接传到了后台。[注:1]

2.将xstring转为string

我们获取到的xstring是GBK的编码,需要转换为string类型,方法有很多[附:1],但都不是SAP Release的,其中一个方法如下:

  CALL FUNCTION 'HR_KR_XSTRING_TO_STRING'
    EXPORTING
      from_codepage = lv_encoding
      in_xstring    = lv_upload_file
    IMPORTING
      out_string    = lv_out_string.

其中from_codepage为Frontend codepage,可使用下面的方法进行获取:

  DATA lv_codepage_numc TYPE cpcodepage.
  CALL FUNCTION 'NLS_GET_FRONTEND_CP'
    EXPORTING
      langu                 = sy-langu
      fetype                = 'MS'
    IMPORTING
      frontend_codepage     = lv_codepage_numc
    EXCEPTIONS
      illegal_syst_codepage = 1
      no_frontend_cp_found  = 2
      internal_or_db_error  = 3
      OTHERS                = 4.
  IF sy-subrc <> 0.
    RETURN.
  ENDIF.

最终获得的codepage为’8404’,传入’HR_KR_XSTRING_TO_STRING’,此时转换正确。
xstring to string

出问题的字符

新建一个文本文档,里面只写一个字:“”,没有回车。然后通过WebDynpro的FileUpload控件上传此文件,可以看到后端获取到的值为:”FE50”。通过查表,可以确定这个“”这个字的GBK编码就是”FE50”。但是使用’HR_KR_XSTRING_TO_STRING’进行转换,得到的string为:”#P”。
做了一个小程序,来查看用到的值
此时我们可以看到转换失败。接下来codepage还用8404,将“”转为xstring,查看一下对应的值为:”AAA2”。

  CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
    EXPORTING
      text     = lv_string_content
      encoding = lv_encoding
    IMPORTING
      buffer   = lv_xstring
    EXCEPTIONS
      failed   = 1
      OTHERS   = 2.

此时出现了不一致的地方:GBK中原本处于FE50-FEA0的字符在SAP系统中没有对应的问文字,而SAP把本身处于FE50-FEA0的字符挪到了AAA2-AAF1(该段处于用户自定义区)。这就导致了GBK中处于FE50-FEA0的字符无法在codepage=8404的情况下正确转换。

Frontend codepage

T-code:SCP 查看系统内的Frontend codepage
我们可以看到8402是属于GB18030-2005,他是对GBK编码的扩充。8404是GB2312,还是GBK。所以SAP使用的8404是GB2312的标准,为了显示GB2312中没有的字,将这些文字放到了用户自定义区。

scp

如何解决转换乱码

使用’HR_KR_XSTRING_TO_STRING’时,codepage使用’8402’,不要使用’NLS_GET_FRONTEND_CP’去获取了。


注释:
1.上传控件其实只是把文本的内容上传。windows下txt文件默认的编码为ANSI,ANSI在Windows下就是根据系统的地区来进行选择编码,简体中文环境下为GBK(梁海在知乎中的回答)。

附录:
1.xstring to string 的方法

**  solution 1
  CALL FUNCTION 'HR_KR_XSTRING_TO_STRING'
    EXPORTING
      from_codepage = lv_encoding
      in_xstring    = lv_upload_file
    IMPORTING
      out_string    = lv_out_string.
**  solution 2
*  CALL FUNCTION 'LXE_COMMON_XSTRING_TO_STRING'
*    EXPORTING
*      IN_CODEPAGE = lv_codepage
*      in_xstring    = lv_upload_file
*    IMPORTING
*      EX_STRING    = lv_out_string.
**  solution 3
*  DATA: lv_filesize TYPE i,
*        lt_bin_data TYPE STANDARD TABLE OF raw255.
*
*  CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
*    EXPORTING
*      buffer        = lv_upload_file
*    IMPORTING
*      output_length = lv_filesize
*    TABLES
*      binary_tab    = lt_bin_data.
*
*  CALL FUNCTION 'SCMS_BINARY_TO_STRING'
*    EXPORTING
*      input_length = lv_filesize
**     MIMETYPE     = ' '
*     ENCODING     = lv_encoding
*    IMPORTING
*      text_buffer  = lv_out_string
**     OUTPUT_LENGTH       =
*    TABLES
*      binary_tab   = lt_bin_data
*    EXCEPTIONS
*      failed       = 1
*      OTHERS       = 2.
*  IF sy-subrc <> 0.
** Implement suitable error handling here
*  ENDIF.
**  solution 4
*lv_out_string =  CL_BCS_CONVERT=>XSTRING_TO_STRING(
*      IV_XSTR = lv_upload_file
*      IV_CP = lv_codepage ).
** solution 5
*  CALL FUNCTION 'ECATT_CONV_XSTRING_TO_STRING'
*    EXPORTING
*      im_xstring        = lv_upload_file
*     IM_ENCODING       = lv_encoding
*   IMPORTING
*     EX_STRING         = lv_out_string   .

2.SAP的编码和GBK编码区别的地方

文字SAP-8404GBK
AAA0AAA0
AAA1D7FE
AAA2FE50
AAA3FE51
AAA4FE52
AAA5FE53
AAA6FE54
AAA7FE55
AAA8FE56
AAA9FE57
AAAAFE58
AAABFE59
AAACFE5A
AAADFE5B
AAAEFE5C
AAAFFE5D
AAB0FE5E
AAB1FE5F
AAB2FE60
AAB3FE61
AAB4FE62
AAB5FE63
AAB6FE64
AAB7FE65
AAB8FE66
AAB9FE67
AABAFE68
AABBFE69
AAC1FE6F
AAD0FE7E
AAD1FE80
AAD2FE81
AAD3FE82
AAD4FE83
AAE0FE8F
AAE1FE90
AAE2FE91
AAE3FE92
AAE4FE93
AAE5FE94
AAE6FE95
AAE7FE96
AAE8FE97
AAE9FE98
AAEAFE99
AAEBFE9A
AAECFE9B
AAEDFE9C
AAEEFE9D
AAEFFE9E
AAF0FE9F
AAF1FEA0

3.相关表
TCP0C
TCP00
TCP00A
TCP0F

4.sap Release的FM
GUI_UPLOAD

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值