ABAP ‘read text‘ 在循环中取值长文本太慢了,来试试效率更高的方法

使用背景:在很多报表中都会取值长文本,一般我们都是使用 read text函数取值,或者 通过ID取值
使用比较简单,但是效率低下,因为在每一循环中都是要取值长文本。
今天来介绍一种复杂一些,但是效率大大提升的方法。

一、源代码

TYPES: BEGIN OF ty_stxl_raw, "压缩的文本
         clustr TYPE stxl-clustr,
         clustd TYPE stxl-clustd,
       END OF ty_stxl_raw.

TYPES:BEGIN OF ty_text, "解压的文本
        tdobject TYPE stxl-tdobject,
        tdid     TYPE stxl-tdid,
        tdname   TYPE stxl-tdname,
        tdline   TYPE string,
      END OF ty_text.

TYPES: BEGIN OF ty_stxl, "直接查询stxl的数据格式
         tdobject TYPE stxl-tdobject,
         tdid     TYPE stxl-tdid,
         tdname   TYPE stxl-tdname,
         clustr   TYPE stxl-clustr,
         clustd   TYPE stxl-clustd,
       END OF ty_stxl.

DATA: lt_stxl TYPE  TABLE OF ty_stxl WITH HEADER LINE. "

DATA: lt_stxl_raw TYPE TABLE OF ty_stxl_raw WITH HEADER LINE,
      ls_stxl_raw TYPE ty_stxl_raw.
DATA lt_tline TYPE STANDARD TABLE OF tline WITH HEADER LINE.

DATA lt_text TYPE  TABLE OF ty_text .
DATA ls_text TYPE ty_text.

"查询销售订单以及订单行
SELECT vbak~vbeln,
       vbap~posnr,
       vbak~ernam,
      CAST( vbak~ernam AS CHAR( 200 ) ) AS longtexth,"抬头长文本
      CAST( vbak~ernam AS CHAR( 200 ) ) AS longtext, "定义一个200长度的字段,里面的内容后面直接清空掉
   concat(  vbak~vbeln  ,vbap~posnr  )  AS tdname "订单 + 订单行  = TDNAME
  FROM vbak
 INNER JOIN vbap ON vbak~vbeln EQ vbap~vbeln
WHERE vbak~vbeln = '0000013856'  "指定的销售订单号,作为测试
  INTO TABLE @DATA(lt_vbak).

"查询抬头文本
"先给我销售订单去重,一个销售订单一行
DATA(lt_vbak_h) = lt_vbak[].
SORT lt_vbak_h BY vbeln .
DELETE ADJACENT DUPLICATES FROM lt_vbak_h COMPARING vbeln .

SELECT stxl~tdobject,
       stxl~tdid,
       stxl~tdname,
       stxl~clustr,
       stxl~clustd
   FROM stxl
INNER JOIN  @lt_vbak_h AS l ON l~vbeln EQ stxl~tdname
WHERE stxl~tdobject = 'VBBK'
AND  stxl~tdid = 'Z003'
AND   stxl~tdspras = @sy-langu
INTO CORRESPONDING FIELDS OF TABLE @lt_stxl.

CLEAR:lt_vbak_h[]."后续使用不到就清空

"查询销售行的长文本
SELECT  stxl~tdobject,
        stxl~tdid,
        stxl~tdname,
        stxl~clustr,
        stxl~clustd
  FROM stxl
 INNER JOIN  @lt_vbak AS l ON l~tdname EQ stxl~tdname  "之所以没有使用FOR ALL 是因为@DATA(LT_VBAK) 产生的TDNAME字段与 STXL~TDNAME 字段长度不一致
  WHERE stxl~tdobject = 'VBBP'
  AND  stxl~tdid = 'Z007'
  AND   stxl~tdspras = @sy-langu
 APPENDING  CORRESPONDING FIELDS OF  TABLE @lt_stxl.

"解压文本
LOOP AT lt_stxl.
  CLEAR:lt_stxl_raw,lt_stxl_raw[], lt_tline,lt_tline[].
  lt_stxl_raw-clustr = lt_stxl-clustr.
  lt_stxl_raw-clustd = lt_stxl-clustd.
  APPEND lt_stxl_raw.
  IMPORT tline = lt_tline FROM INTERNAL TABLE lt_stxl_raw.

  LOOP AT lt_tline.
    ls_text-tdline = ls_text-tdline && lt_tline-tdline.
  ENDLOOP.
  ls_text-tdobject = lt_stxl-tdobject.
  ls_text-tdid = lt_stxl-tdid.
  ls_text-tdname = lt_stxl-tdname.
  IF ls_text-tdline NE ''.
    INSERT ls_text INTO TABLE lt_text.
  ENDIF.
  CLEAR ls_text.
ENDLOOP.

SORT lt_text BY tdobject  tdid   tdname   ."排序为二分法做准备
DELETE ADJACENT DUPLICATES FROM lt_text COMPARING tdobject  tdid   tdname.

"匹配到ALV内表中
LOOP AT lt_vbak INTO DATA(ls_vbak).
  CLEAR: ls_vbak-longtext ,ls_vbak-longtexth."先清空长文本

  "取值销售订单抬头长文本
  READ TABLE lt_text INTO ls_text WITH  KEY tdobject = 'VBBK' tdid = 'Z003' tdname = ls_vbak-vbeln BINARY SEARCH.
  IF sy-subrc = 0.
    ls_vbak-longtexth = ls_text-tdline.
  ENDIF.
  CLEAR ls_text.

  "销售行文本
  READ TABLE lt_text INTO ls_text WITH KEY tdobject = 'VBBP' tdid = 'Z007' tdname = ls_vbak-tdname BINARY SEARCH.
  IF sy-subrc = 0.
    ls_vbak-longtext = ls_text-tdline.
  ENDIF.
  CLEAR ls_text .


  MODIFY lt_vbak FROM ls_vbak.
  CLEAR:ls_vbak.
ENDLOOP.

cl_demo_output=>display_data( lt_vbak  ).

二、结果展示
在这里插入图片描述

本例子中,只要改改销售订单,以及长文本id就能直接使用了,测试起来蛮方便的,而且上述例子中有取值抬头和长文本的两种示范,方便你复制使用。

三、效率提升点
1.没有长文本的数据不再SQL,减少数据量。
2.二分法匹配。
3.避免在循环中取数匹配。

四、应用场景
当你取值多个长文本,并且数据量大时候就可以考虑这个方法了。

  • 11
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值