CL_GUI_FRONTEND_SERVICES 导入 EXCEL 到系统文件时,长度不够数据被分成多行的问题解决

举报
雨绸缪 发表于 2023/07/24 16:41:54 2023/07/24
【摘要】 扩展 Excel 上传字符数网上有很多教大家把 ALSM_EXCEL_TO_INTERNAL_TABLE 功能模块复制出来,然后增大每次导入 Excel 的单元格字符扩大的方法。这里简单介绍一下:通过 SE37 可以看到这个函数的表结构关联了 ALSMEX_TABLINE 这个类型,描述为:具有 Excel 数据的表行。点进去能看到这个结构分别有三个组件:ROW、COL 和 VALUE ,...

扩展 Excel 上传字符数

网上有很多教大家把 ALSM_EXCEL_TO_INTERNAL_TABLE 功能模块复制出来,然后增大每次导入 Excel 的单元格字符扩大的方法。这里简单介绍一下:

通过 SE37 可以看到这个函数的表结构关联了 ALSMEX_TABLINE 这个类型,描述为:具有 Excel 数据的表行。

点进去能看到这个结构分别有三个组件:ROWCOLVALUE ,这三个也非常好理解,分别对应 Excel 的行、列和单元格的值。但是明显可以看到这个 VALUE 的数据类型为 CHAR50,意味着如果单元格的字符数超过 50 个字符的话,就会数据丢失,导致上传数据信息不全。

因此,我们会将自定一个结构,然后将这个类型扩大,比如定义一个 ZALSMEX_TABLINE3 的结构,然后将这个 VALUE 的值扩大到有 4096 个字符的文本。

image.png

然后我就需要自定义一个 ZALSM_EXCEL_TO_INTERNAL_TABLE3 的函数模块,将中的参数 INTERN 类型化为刚刚自定义的 ZALSMEX_TABLINE3,类似下图:

image.png

保持导入参数和源代码和 ALSM_EXCEL_TO_INTERNAL_TABLE 的一致。至此,我们就完成了一个可以在 Excel 上传数据中扩大单元格字符数。

但是

但是,当我们上传的 Excel 字符多了之后,就会发现有时候上传 Excel 明明在 Excel 中只会有一行,但是到了 SAP 变成了两行,如下图:

Excel 原始数据:

image.png

上传到 SAP 之后,显示为两行了:

image.png

只能,将这个数据进行 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,即第二行,找到问题了,但是该如何解决呢。

image.png

问题定位

既然是这个函数模块的问题,那么就需要进这个函数里面找问题的解决方法,最后找到了这段代码:

* 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) 变量:

image.png

然后内表 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> 数据为空,直到:

image.png

<table> 中的数据被读到一行,然后不同的单元格用 # 分开,类似这样的数据:

image.png

逐步研究之后,说明 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,其中一段如下 :

image.png

最后当自定义 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 数据导入,上传成功截图:

image.png

最后,问题解决,探索真有趣~

温馨提示: 本方案也就针对大量文本数据传输到自定义字段,其他建议还是使用官方的函数和类,避免发生系统错误。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。