问题的起因是通过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是对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 个。
WebDynpro中使用FileUpload控件进行文件的上传,控件的data属性要绑定给一个xstring类型的Attribute(具体如何实现附件上传本文不具体论述)。我们可以读取这个Attribute值,来查看文件传到SAP后端之后的情况。
现在我们先新建一个文本文档,里面只写一个字:“﨩”,没有回车。然后通过WebDynpro的FileUpload控件上传此文件,可以看到后端获取到的值为:”FE4F”。
我们再查看前面的GBK举例表,在GBK编码中“﨩”的编码也是“FE4F”,这代表着SAP把txt文档的内容直接传到了后台。[注:1]
我们获取到的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’,此时转换正确。
新建一个文本文档,里面只写一个字:“”,没有回车。然后通过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的情况下正确转换。
T-code:SCP 查看系统内的Frontend codepage
我们可以看到8402是属于GB18030-2005,他是对GBK编码的扩充。8404是GB2312,还是GBK。所以SAP使用的8404是GB2312的标准,为了显示GB2312中没有的字,将这些文字放到了用户自定义区。
使用’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