CL_GUI_FRONTEND_SERVICES 导入 EXCEL 到系统文件时,长度不够数据被分成多行的问题解决
扩展 Excel 上传字符数
网上有很多教大家把 ALSM_EXCEL_TO_INTERNAL_TABLE
功能模块复制出来,然后增大每次导入 Excel 的单元格字符扩大的方法。这里简单介绍一下:
通过 SE37
可以看到这个函数的表结构关联了 ALSMEX_TABLINE
这个类型,描述为:具有 Excel 数据的表行。
点进去能看到这个结构分别有三个组件:ROW
、COL
和 VALUE
,这三个也非常好理解,分别对应 Excel 的行、列和单元格的值。但是明显可以看到这个 VALUE 的数据类型为 CHAR50
,意味着如果单元格的字符数超过 50 个字符的话,就会数据丢失,导致上传数据信息不全。
因此,我们会将自定一个结构,然后将这个类型扩大,比如定义一个 ZALSMEX_TABLINE3
的结构,然后将这个 VALUE
的值扩大到有 4096 个字符的文本。
然后我就需要自定义一个 ZALSM_EXCEL_TO_INTERNAL_TABLE3
的函数模块,将表中的参数 INTERN
类型化为刚刚自定义的 ZALSMEX_TABLINE3
,类似下图:
保持导入参数和源代码和 ALSM_EXCEL_TO_INTERNAL_TABLE
的一致。至此,我们就完成了一个可以在 Excel 上传数据中扩大单元格字符数。
但是
但是,当我们上传的 Excel 字符多了之后,就会发现有时候上传 Excel 明明在 Excel 中只会有一行,但是到了 SAP 变成了两行,如下图:
Excel 原始数据:
上传到 SAP 之后,显示为两行了:
只能,将这个数据进行 Debug,在使用 ZALSM_EXCEL_TO_INTERNAL_TABLE3
的地方打上断点,
DATA lt_excel TYPE TABLE OF zalsmex_tabline3 WITH HEADER LINE.
CALL FUNCTION 'ZALSM_EXCEL_TO_INTERNAL_TABLE3'
EXPORTING
filename = p_path
i_begin_col = 1 "1
i_begin_row = 3 "4
i_end_col = 300 "50
i_end_row = 10000
sheet_name = '基础数据'
TABLES
intern = lt_excel
EXCEPTIONS
inconsistent_parameters = 1
upload_ole = 2
OTHERS = 3.
发现在 Excel 的第 99 列数据 ROW
变量变成了 2,即第二行,找到问题了,但是该如何解决呢。
问题定位
既然是这个函数模块的问题,那么就需要进这个函数里面找问题的解决方法,最后找到了这段代码:
* read clipboard into ABAP
CALL METHOD cl_gui_frontend_services=>clipboard_import
IMPORTING
data = excel_tab
EXCEPTIONS
cntl_error = 1
* ERROR_NO_GUI = 2
* NOT_SUPPORTED_BY_GUI = 3
OTHERS = 4.
IF sy-subrc <> 0.
MESSAGE a037(alsmex).
ENDIF.
这段代码会将复制板中的数据一次导入到 SAP 的内表 excel_tab
中,而这个内表的结构被定义为:
DATA: excel_tab TYPE ty_t_sender.
而这个 ty_t_sender
的类型又是什么呢?顺藤摸瓜,定义如下:
* value of excel-cell
TYPES: ty_d_itabvalue TYPE alsmex_tabline-value,
* internal table containing the excel data
ty_t_itab TYPE alsmex_tabline OCCURS 0,
* line type of sender table
BEGIN OF ty_s_senderline,
line(4096) TYPE c,
END OF ty_s_senderline,
* sender table
ty_t_sender TYPE ty_s_senderline OCCURS 0.
就是这个 line(4096)
变量,自然而然会想,是不是这个变量装不下 Excel 的值呢?
然后又去看了一下 CLIPBOARD_IMPORT
方法,其中也定义了这个 line(4096)
变量:
然后内表 tab
的定义就是:
DATA tab like table of line.
然后看哪个地方将数据传入这个 tab
内表呢,双击 tab
,定位到这段代码:
* send data to frontend
CALL FUNCTION 'DP_STRETCH_SIMPLE_TABLE'
EXPORTING
copy_lines = ' '
IMPORTING
stretched_data_ref = table_ref
TABLES
data = data
EXCEPTIONS
DP_ERROR_MULTIPLE_COLS = 1
DP_ERROR_NOT_CHARLIKE = 2.
IF sy-subrc = 0.
* ASSIGN table_ref->* TO <table>.
ASSIGN tab TO <table>. " just take the very wide table
ELSE.
ASSIGN data TO <table>.
ENDIF.
那我们就把断点打到此处,边打断点边逐步执行,会发现 <table>
数据为空,直到:
<table>
中的数据被读到一行,然后不同的单元格用 #
分开,类似这样的数据:
逐步研究之后,说明 SAP 会先将数据读取到一个地方,然后再按照 #
分隔符将数据分开,数据转换被写在这段函数里:
PERFORM separated_to_intern_convert TABLES excel_tab intern
USING ld_separator.
Debug 也能看到 LD_SEPARATOR
的值为 #
。
自此,就找到原因被分成两行的原因:SAP 将 Excel 中所有的单元格读到一个内表的一行中,这些数据用 #
分开,而这行如果超过 4096 个字符,就会被拆成两行及以上。
问题解决
将类 CL_GUI_FRONTEND_SERVICES
复制为 Z_CL_GUI_FRONTEND_SERVICES
自定义类,如果这个时候激活,会出现 Access to protected attribute/methods is not allowed.
。比如:
Access to protected attribute "H_CONTROL" is not allowed.
那是因为 CL_GUI_FRONTEND_SERVICES
有很多自引用方法,因此需要在 Z_CL_GUI_FRONTEND_SERVICES
类中,点击 Source Code-Based
(基于源代码),将所有的 CL_GUI_FRONTEND_SERVICES
替换为 Z_CL_GUI_FRONTEND_SERVICES
,其中一段如下 :
最后当自定义 Z_CL_GUI_FRONTEND_SERVICES
类激活完成之后,我们就可以在 ZALSM_EXCEL_TO_INTERNAL_TABLE3
进行使用:
* read clipboard into ABAP
CALL METHOD z_cl_gui_frontend_services=>clipboard_import
IMPORTING
data = excel_tab
EXCEPTIONS
cntl_error = 1
* ERROR_NO_GUI = 2
* NOT_SUPPORTED_BY_GUI = 3
OTHERS = 4.
IF sy-subrc <> 0.
MESSAGE a037(alsmex).
ENDIF.
* clear clipboard
REFRESH excel_tab.
CALL METHOD z_cl_gui_frontend_services=>clipboard_export
IMPORTING
data = excel_tab
CHANGING
rc = ld_rc
EXCEPTIONS
cntl_error = 1
* ERROR_NO_GUI = 2
* NOT_SUPPORTED_BY_GUI = 3
OTHERS = 4.
最后,使用 ZALSM_EXCEL_TO_INTERNAL_TABLE3
进行 Excel 数据导入,上传成功截图:
最后,问题解决,探索真有趣~
温馨提示: 本方案也就针对大量文本数据传输到自定义字段,其他建议还是使用官方的函数和类,避免发生系统错误。
- 点赞
- 收藏
- 关注作者
评论(0)