SAP ABAP转换特殊字符乱码

问题的起因是通过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
SAP ABAP转换特殊字符乱码_第1张图片

SAP端的基本姿势

1.WebDynpro中的上传特点

WebDynpro中使用FileUpload控件进行文件的上传,控件的data属性要绑定给一个xstring类型的Attribute(具体如何实现附件上传本文不具体论述)。我们可以读取这个Attribute值,来查看文件传到SAP后端之后的情况。
现在我们先新建一个文本文档,里面只写一个字:“﨩”,没有回车。然后通过WebDynpro的FileUpload控件上传此文件,可以看到后端获取到的值为:”FE4F”。
SAP ABAP转换特殊字符乱码_第2张图片
我们再查看前面的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’,此时转换正确。
SAP ABAP转换特殊字符乱码_第3张图片

出问题的字符

新建一个文本文档,里面只写一个字:“”,没有回车。然后通过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中没有的字,将这些文字放到了用户自定义区。

SAP ABAP转换特殊字符乱码_第4张图片

如何解决转换乱码

使用’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-8404 GBK
AAA0 AAA0
AAA1 D7FE
AAA2 FE50
AAA3 FE51
AAA4 FE52
AAA5 FE53
AAA6 FE54
AAA7 FE55
AAA8 FE56
AAA9 FE57
AAAA FE58
AAAB FE59
AAAC FE5A
AAAD FE5B
AAAE FE5C
AAAF FE5D
AAB0 FE5E
AAB1 FE5F
AAB2 FE60
AAB3 FE61
AAB4 FE62
AAB5 FE63
AAB6 FE64
AAB7 FE65
AAB8 FE66
AAB9 FE67
AABA FE68
AABB FE69
AAC1 FE6F
AAD0 FE7E
AAD1 FE80
AAD2 FE81
AAD3 FE82
AAD4 FE83
AAE0 FE8F
AAE1 FE90
AAE2 FE91
AAE3 FE92
AAE4 FE93
AAE5 FE94
AAE6 FE95
AAE7 FE96
AAE8 FE97
AAE9 FE98
AAEA FE99
AAEB FE9A
AAEC FE9B
AAED FE9C
AAEE FE9D
AAEF FE9E
AAF0 FE9F
AAF1 FEA0

3.相关表
TCP0C
TCP00
TCP00A
TCP0F

4.sap Release的FM
GUI_UPLOAD

你可能感兴趣的:(总结,sap)