SAP Kernel升级造成的Excel导出错误

问题的起因和现象

我们的basis一直认为,SAP的Knernel升级对一般用户的操作是不会影响的,因此在做硬件扩容的时候,顺便把Kernel从185升级到278。
之后用户在ALV报表中导出到Excel的时候,出现下面的错误:

Runtime Errors         CONVT_CODEPAGE
Exception              CX_SY_CONVERSION_CODEPAGE
Short text
A character set conversion is not possible.
发生了什么?
At the conversion of a text from codepage '8400' to codepage '4110':

- a character was found that cannot be displayed in one of the two codepages;
- or it was detected that this conversion is not supported

The running ABAP program 'CL_SALV_BS_TT_ALVXML==========CP' had to be terminated as the conversion would have produced incorrect data.
The number of characters that could not be displayed (and therefore not be converted), is 1. If this number is 0, the second error case, as mentioned above, has occurred.

源码摘录(Source code has changed)
Line  SourceCde
1 method transform.
2
3   data: lv_transformation_name type string.
4
5   lv_transformation_name = 'SALV_BS_XMLSTRUC_TO_ALVXML'.
6
7   super->transform( r_xml_struc ).
8
9   field-symbols:
10      type any.
11
12   assign me->r_xml_struc->r_data->* to .
13
>>>>>   try.
16       call transformation (lv_transformation_name)
17         source alv_bs_xml =
18         result xml me->alv_xml.
19     catch cx_xslt_abap_call_error.                      "#EC NO_HANDLER
20 *  Ursache:Fehler beim Aufruf einer ABAP Methode aus XSLT
21 *  Laufzeitfehler: XSLT_METH_ERROR
22     catch cx_xslt_deserialization_error.                "#EC NO_HANDLER
23 *  Ursache:Fehler bei der Deserialisierung
24 *  Laufzeitfehler: XML_NOT_SUPPORTED
25     catch cx_xslt_format_error.                         "#EC NO_HANDLER
26 *  Ursache:Dokument ist nicht im asXML-Format
27 *  Laufzeitfehler: XML_FORMAT_ERROR
28     catch cx_xslt_runtime_error.                        "#EC NO_HANDLER
29 *  Ursache:Fehler im XSLT-Prozessor
30 *  Laufzeitfehler: UNCAUGHT_EXCEPTION
31     catch cx_xslt_serialization_error.                  "#EC NO_HANDLER
32 *  Ursache:Fehler bei der Serialisierung
33 *  Laufzeitfehler: XML_NOT_SUPPORTED
34   endtry.

给用户的临时解决方案

使用导出带本地文件的功能,可以将ALV报表导出成csv格式的伪excel文件。

寻求SAP公司的帮助

因为Excel导出的功能使用非常普遍,用户主动反馈错误很多,因此给sap发了very high的message。根据sap的回复,实施了note 1349963,但问题依然没有解决。
sap后来的回复建议我们把sap kernel升级到最新版本,因涉及系统停机,暂时无法在生产系统验证。

系统测试和验证

根据用户的反馈,并不是所有的ALV报表都无法导出到Excel。根据用户的使用使用情况,使用本地文件导出功能,分别提取能够导出和无法导出的两个报表内容。在Firefox的Regular Expression Tester里面,使用正则表达式[\u4e00-\u9fa5]|[a-zA-Z0-9]1,把汉字、字母、数字删除掉后进行对比。发现无法导出的报表里面,部分客户描述的尾部为特殊字符|。

使用XD03查看这个客户,发现客户描述字段的显示乱码。根据对sap客户相关表的了解,问题的根因基本弄清楚了:在维护客户的情况,客户名称保存在40位的ADRC-NAME1字段中,同时将35位保存在KNA1-NAME1字段中,对于超过35位的ADRC-NAME1进行截取时,如果第35位不是汉字的第一个字节,就出现XD03中客户名称显示乱码的情况。

业务使用的报表取客户描述时候,一般都使的KNA1-NAME1字段的内容,在ALV报表中最后的半个汉字显示为?。联系业务部门把客户的名称修改成少于35位后,原来无法导出的报表导出功能恢复正常。

理清Excel导出错误与SAP Kernel升级的关系

在QAS环境把Kernel回退到185版本,内容中有?的报表也可以正常导出。重新把Kernel升级到278版本后,内容中有?的报表无法导出。由此证明Excel导出错误确实是由于Kernel升级造成的。
在QAS环境,根据sap在message中的建议,把Kernel升级到最新的291版本版本,问题依然没有解决。暂时认为只能停机把Kernel恢复成185版本。

最终解决方案

根据note 1241706的内容,因为corrupted characters导致调用call transformation语句发生CX_SY_CONVERSION_CODEPAGE异常,可以使用调用 CL_SXML_STRING_WRITER作为替代方案(需要设置GNORE_CONVERSION_ERRORS =ABAP_TRUE)。

根据note 1441793的描述,可以解决我们碰到的这个错误。但是这个notes的solution居然是导入support package 22,这个动作太大,也无法实施。

使用snote工具也无法自己实施这个note。根据这个note的具体修改内容,手工修改CL_SALV_BS_TT_ALVXML类的TRANSFORM方法,部分内容改成note 1241706提供的关键源代码,关键代码如下:

try.
*      call transformation (l_transformation_name)
*        source alv_bs_xml =
*        result xml me->alv_xml.

" Instead of using a xstring as result, we need to use a string_writer.
" Reason is the parameter "ignore_conversion_errors" which makes the
" transformation more robust in case of conversion errors
" (e.g. because of kernel update)
" => prevents dump CONVT_CODEPAGE / CX_SY_CONVERSION_CODEPAGE
cl_sxml_string_writer=>create(
exporting
type                     = if_sxml=>co_xt_xml10    " xml format
ignore_conversion_errors = abap_true    " ignore conversion errors
receiving
writer                   = lr_xml_string_writer    " sxml writer factory
).

call transformation (l_transformation_name)
source alv_bs_xml =
result xml lr_xml_string_writer.

me->alv_xml = lr_xml_string_writer->GET_OUTPUT( ).

以上两个步骤在QAS系统实施后,测试验证内容中有?的报表可以正常导出。按同样的方法在PRD系统进行修改,同时回退note 1349963,在没有停机和导入support package的情况下,问题最终得到解决。

备注:

1. [\u4e00-\u9fa5]这样的表达式在UE和EditPlus都不支持。

One Response

Subscribe to comments with RSS.

  • 翱翔云天 says:

    有点想当然啦,kernel的升级是要非常小心滴,sap列出的可能的影响并不一定全面,一般在不出现问题的情况下,少动为妙。。。