当前位置: 首页 > 工具软件 > kLoop > 使用案例 >

ABAP中的loop

从劲
2023-12-01

1 原则

loop在ABAP中使用太多,尽量不要在loop中用loop.这样的结果是行数太多,非常的影响速度,这可能是几何倍数增加循环次数。但如果数据量很少,也可以使用,如果没办法,那只有使用,下面是一个DEMO,按正常使用是loop table into wa_table

modify table from wa_table
endloop.
以上是正确的格式,在实际中很多是用到带表头的内表,然后都不用加工作区.

2 demo

REPORT zmm051.
TYPE-POOLS: slis.
TABLES:MKOL,mbew,marc,t024,agr_users, mseg.
*数据声明
DATA: BEGIN OF item OCCURS 0,
        meins      LIKE mara-meins,
        matnr      LIKE mseg-matnr,
        maktx      LIKE makt-maktx,
        werks      LIKE mseg-werks,
        bwart      LIKE mseg-bwart,       "移动类型
        lgort      LIKE mseg-lgort,
        budat_mkpf LIKE mseg-budat_mkpf,
        menge      LIKE mseg-menge,"数量
        zrkl       TYPE p DECIMALS 3,     "当前库存"总入库量
        zckl       TYPE p DECIMALS 3,     "当前库存"总出库量
        zbyrk      TYPE p DECIMALS 3,"     "到最小日期期初库存中本月入库数量
        zbyrk1     TYPE p DECIMALS 3,"    "到最大日期期初库存中本月入库数量
        zsyjy      TYPE p DECIMALS 3,"    "上月结余库存

        za         TYPE p DECIMALS 3,"   LIKE mard-labst,"当前库存"期初库存
        zb         TYPE p DECIMALS 3,"   LIKE mard-labst,"当前库存期末库存
        "zb         LIKE mseg-menge,"期末库存
        shkzg      LIKE mseg-shkzg,
        peinh      LIKE mbew-peinh,"价格单位
        stprs      LIKE mbew-stprs,"标准价格
        bzdj       LIKE mbew-stprs,"标准单价
        zajz       TYPE p DECIMALS 3,"    LIKE mbew-stprs,"期初库存价值
        zbjz       TYPE p DECIMALS 3,"   LIKE mbew-stprs,"期末库存价值
        zrkjz      TYPE p DECIMALS 3,"   LIKE mbew-stprs,"总入库价值
        zckjz      TYPE p DECIMALS 3,"   LIKE mbew-stprs,"总出库价值
        ekgrp      LIKE marc-ekgrp,"采购组
        eknam      LIKE t024-eknam,"采购组描述
        labst      LIKE mard-labst,"当前库存
        zzqt       LIKE mard-labst,"清退数量
        zcrk       TYPE i,         "总装整车入库数量
        zcxs       TYPE i,         "整车销售数量
        zeile      TYPE mseg-zeile,         "整车销售数量
        klabs      TYPE mard-klabs,         "寄售当前库存
        lifnr       like mseg-lifnr,
        sobkz       like  mseg-sobkz,
      END OF item.

DATA: gd_repid LIKE sy-repid.
DATA: i_grid_settings TYPE lvc_s_glay.
DATA: ita LIKE TABLE OF item WITH HEADER LINE.
DATA: itb LIKE TABLE OF item WITH HEADER LINE.
DATA: itc LIKE TABLE OF item WITH HEADER LINE.               "输出到sf 的抬头数据
DATA: lft_i LIKE TABLE OF item WITH HEADER LINE.               "输出到sf 的项目数据
DATA: is_i LIKE TABLE OF item  WITH HEADER LINE.
DATA: lt_ztpp015 LIKE TABLE OF ztpp015 WITH HEADER LINE.
DATA: l_zdbls   LIKE zjlst-zdbls,
      l_con(30),"过度变量
      l_num     TYPE numc4.
DATA: p_zjlst LIKE TABLE OF zjlst  WITH HEADER LINE.
DATA: l_ztsycs LIKE TABLE OF ztsycs WITH HEADER LINE.
DATA: afield TYPE slis_fieldcat_alv.
DATA: fieldcat TYPE TABLE OF slis_fieldcat_alv WITH HEADER LINE.
DATA: layout TYPE slis_layout_alv.
DATA: l_pos TYPE i VALUE 1.
DATA: s_i TYPE i .
DATA: l_erdat LIKE sy-datum.
DATA: l_a LIKE sy-datum,l_b LIKE sy-datum."年度月度控制
DATA: wa_i LIKE item.
DATA: zbz(1).
DATA: BEGIN OF itd OCCURS 0 ,
        mblnr LIKE mseg-mblnr,
        mjahr LIKE mseg-mjahr,
      END OF itd.
*宏的定义
DEFINE fill.
  afield-col_pos = l_pos.
  afield-fieldname = &1.
  afield-seltext_l = &2.
  afield-no_zero   = &3.
  afield-key       = &4.
   afield-qfieldname    = &5.   "  去掉小数点后边0      = &5.

*  IF afield-fieldname = 'ZA'.
*    afield-DECIMALS_OUT = '0'.         "去掉小数点后边0
* ENDIF.
*  IF afield-fieldname = 'ZCKL'.
*    afield-DECIMALS_OUT = '0'.         "去掉小数点后边0
* ENDIF.
* IF afield-fieldname = 'ZZQT'.
*    afield-DECIMALS_OUT = '0'.         "去掉小数点后边0
* ENDIF.
* IF afield-fieldname = 'ZRKL'.
*    afield-DECIMALS_OUT = '0'.         "去掉小数点后边0
* ENDIF.
* IF afield-fieldname = 'ZB'.
*    afield-DECIMALS_OUT = '0'.         "去掉小数点后边0
* ENDIF.
* IF afield-fieldname = 'ZCRK'.
*    afield-DECIMALS_OUT = '0'.         "去掉小数点后边0
* ENDIF.
* IF afield-fieldname = 'ZCXS'.
*    afield-DECIMALS_OUT = '0'.         "去掉小数点后边0
* ENDIF.
  append afield to fieldcat.
  clear afield.
  l_pos = l_pos + 1.
END-OF-DEFINITION.
*筛选界面
SELECTION-SCREEN BEGIN OF BLOCK blc WITH FRAME TITLE text-001.
PARAMETERS:         p_werks  LIKE mseg-werks OBLIGATORY DEFAULT '2100',
                    p_lgort  LIKE mseg-lgort OBLIGATORY.
SELECT-OPTIONS      p_matnr  FOR mseg-matnr .
SELECT-OPTIONS     P_LIFNR  FOR mkol-LIFNR .
SELECT-OPTIONS      p_ekgrp  FOR marc-ekgrp .
SELECT-OPTIONS      p_erdat  FOR mseg-budat_mkpf OBLIGATORY .
SELECTION-SCREEN END OF BLOCK blc.

INITIALIZATION.
  p_erdat-option = 'BT'.
  p_erdat-sign = 'I'.
  p_erdat-low = sy-datum.
  p_erdat-low+6(2) = '01'.
  p_erdat-high = sy-datum.
  APPEND p_erdat.
*取数
START-OF-SELECTION.
  PERFORM frm_auth_check.
  PERFORM frm_get_data.                 "获取数据
  IF item[] IS NOT INITIAL.
    PERFORM frm_modify.
    PERFORM frm_show_data.
  ELSE.
    MESSAGE s001(00) WITH '没有查询到数据'.
  ENDIF.
*&---------------------------------------------------------------------*
*&      Form  FRM_GET_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_get_data .
  CLEAR:l_a,l_b.
  l_a = p_erdat-low.
  l_b = sy-datum.
  "取当前所有物料抬头数据
  SELECT MARD~matnr MARD~lgort MARD~werks MARD~labst MARD~klabs  INTO CORRESPONDING FIELDS OF TABLE item
    FROM mard
    WHERE MARD~werks = p_werks
    AND MARD~lgort = p_lgort
    AND MARD~matnr IN p_matnr.

*  SELECT mblnr mjahr INTO CORRESPONDING FIELDS OF TABLE itd
*  FROM mkpf CLIENT SPECIFIED
*  WHERE budat BETWEEN l_a AND l_b
*  AND mandt = sy-mandt.
*  "取一段时间内总入库量
*  IF itd[] IS NOT INITIAL .
*    SELECT zeile matnr lgort budat_mkpf bwart menge shkzg INTO CORRESPONDING FIELDS OF TABLE ita
*    FROM mseg
*    CLIENT SPECIFIED "取出物料、库存地点、物料金额、移动类型、数量、借贷标识
*    FOR ALL ENTRIES IN itd
*    WHERE
*    mandt = sy-mandt
*    AND mjahr = itd-mjahr
*    AND mblnr = itd-mblnr
*    AND matnr IN p_matnr
*    AND werks = p_werks
*    AND lgort = p_lgort.
*  ENDIF.

*  add by wanghc 20191224 将上述逻辑重构
  SELECT zeile matnr lgort budat_mkpf bwart menge shkzg  sobkz INTO CORRESPONDING FIELDS OF TABLE ita FROM mseg
  WHERE werks  = p_werks
    AND lgort = p_lgort
    AND matnr IN p_matnr
*    AND lifnr IN P_LIFNR
    AND budat_mkpf BETWEEN l_a AND l_b
    AND shkzg <> ''.

  LOOP AT item.
    LOOP AT ita WHERE matnr = item-matnr AND lgort = item-lgort AND budat_mkpf <= p_erdat-high ."总入库量取值
      IF ita-shkzg = 'S'.
        item-zrkl = item-zrkl + ita-menge.
      ELSE.
        item-zckl = item-zckl + ita-menge.
      ENDIF.
    ENDLOOP.
*    if ita-lifnr is not INITIAL and ( Ita-sobkz = 'K' ) .
*    item-lifnr = ita-lifnr.                                     " add it by jingguilin 20210330
*    ENDIF.
    MODIFY item.
    CLEAR  item.
  ENDLOOP.

  "屏幕小日期到今日入库数量取值
  LOOP AT ita.
    IF ita-shkzg = 'H'.
      ita-menge =  - ita-menge.
    ENDIF.
    MODIFY  ita.
  ENDLOOP.
  LOOP AT item.
    LOOP AT ita WHERE matnr = item-matnr AND lgort = item-lgort. "AND budat_mkpf < l_erdat.
      item-zbyrk = item-zbyrk + ita-menge.
    ENDLOOP.
    MODIFY item.
    CLEAR  item.
  ENDLOOP.
  """"""最大日期到今日入库数量取值
  LOOP AT item.
    LOOP AT ita WHERE matnr = item-matnr AND lgort = item-lgort AND budat_mkpf > p_erdat-high .
      item-zbyrk1 = item-zbyrk1 + ita-menge.
    ENDLOOP.

    MODIFY item.

    CLEAR  item.
  ENDLOOP.
  """"""""""""""""""
  DATA: l_n LIKE mardh-lfgja,l_m LIKE mardh-lfmon.
  DATA: l_c LIKE mseg-menge,l_d LIKE mseg-menge.
  LOOP AT item.
    CLEAR:l_a,l_b.
*    LOOP AT itb.
*      SELECT SUM( menge ) INTO l_c FROM mseg
*           INNER JOIN mara ON mseg~matnr = mara~matnr WHERE mtart ='FERT'                 " commenit by jingguilin 20210414
*        AND bwart IN ('411')
*        AND budat_mkpf IN p_erdat
*        AND mseg~matnr = item-matnr
*        AND lgort IN ( '1001','1004' )"= '1001' OR lgort = '1005'
*        AND werks = p_werks.
*      SELECT SUM( menge ) INTO l_d FROM mseg
*             INNER JOIN mara ON mseg~matnr = mara~matnr WHERE mtart ='FERT'
*          AND bwart IN ('412')
*          AND budat_mkpf IN p_erdat
*          AND mseg~matnr = item-matnr
*          AND lgort IN ( '1001','1004' )
*          AND werks = p_werks.
*      itb-zcrk = l_c - l_d.
*      MODIFY itb.
*    ENDLOOP.
    SELECT SINGLE maktx INTO item-maktx FROM makt WHERE matnr = item-matnr AND spras = '1'.
    SELECT SINGLE ekgrp INTO item-ekgrp FROM marc WHERE matnr = item-matnr.
    SELECT SINGLE eknam INTO item-eknam FROM t024 WHERE ekgrp = item-ekgrp.
    SELECT SINGLE stprs peinh INTO (item-stprs,item-peinh) FROM mbew WHERE matnr = item-matnr AND bwkey = p_werks."标准价格
    SELECT SINGLE meins INTO item-meins FROM mara WHERE matnr = item-matnr.
    item-za = item-labst + item-klabs - item-zbyrk.
    item-zb = item-labst + item-klabs - item-zbyrk1.
    "item-bzdj = item-stprs / item-peinh."标准单价
    item-zajz = item-za * item-stprs / item-peinh."期初库存价值
    item-zbjz = item-zb * item-stprs / item-peinh."期末库存价值
    item-zrkjz = item-zrkl * item-stprs / item-peinh."总入库价值
    item-zckjz = item-zckl * item-stprs / item-peinh."总出库价值
    item-zzqt = item-za - item-zckl.
    MODIFY item.
  ENDLOOP.
  DELETE item WHERE za = 0 AND zb = 0 AND zrkl = 0 AND zckl = 0.
  IF p_ekgrp IS NOT INITIAL.
    DELETE item WHERE ekgrp NOT IN p_ekgrp.
  ENDIF.
ENDFORM.                    " FRM_GET_DATA
*&---------------------------------------------------------------------*
*&      Form  FRM_SHOW_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_show_data .
  i_grid_settings-edt_cll_cb  = 'X' .            "显示界面可编辑字段上修改了数据,回车后就会立即将内表的数据也修改
  layout-colwidth_optimize    = 'X'.                "设置字段列宽自适应
  layout-zebra             = 'X'.

  CLEAR afield.
  REFRESH fieldcat.

  fill  'MATNR'      '物料编号'             '' '' ''.
  fill  'MAKTX'      '物料描述'             '' '' ''.
  fill  'EKGRP'      '采购组'               '' '' ''.
  fill  'EKNAM'      '采购组描述'           '' '' ''.
  fill  'LGORT'      '仓储地点'             '' '' ''.

  fill  'ZA'         '期初库存'             'X' '' 'MEINS'.
  IF zbz = 'X'.
    fill  'ZAJZ'       '期初库存价值'         'X' '' ''.
  ENDIF.
  fill  'ZCKL'       '总出库量'             'X' '' 'MEINS'.
  IF zbz = 'X'.
    fill  'ZCKJZ'      '总出库价值'           'X' '' ''.
  ENDIF.
  IF p_lgort = '5001'.
    fill  'ZZQT'     '清退数量'               'X' '' 'MEINS'.
  ENDIF.
  fill  'ZRKL'      '总入库量'              'X' '' 'MEINS'.
  IF zbz = 'X'.
    fill  'ZRKJZ'     '总入库价值'            'X' '' ''.
  ENDIF.
  fill  'ZB'        '期末库存'              'X' '' 'MEINS'.
  IF zbz = 'X'.
    fill  'ZBJZ'      '期末库存价值'          'X' '' ''.
  ENDIF.


  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_grid_settings         = i_grid_settings                 "显示界面可编辑字段上修改了数据,回车后就会立即将内表的数据也修改
      i_callback_program      = sy-cprog "sy-repid                        "标记当前程序
      it_fieldcat             = fieldcat[]
      is_layout               = layout
      i_callback_user_command = 'USER_COMMAND'
      "i_callback_pf_status_set = 'SET_STATUS'
    TABLES
      t_outtab                = item.
ENDFORM.                    " FRM_SHOW_DATA

FORM user_command USING rf_ucomm  LIKE sy-ucomm
                       rs        TYPE slis_selfield .
  rs-refresh = 'X'.

  CASE rf_ucomm.
    WHEN '&IC1'.
      READ TABLE item INTO wa_i INDEX rs-tabindex.
      IF  rs-fieldname = 'MATNR'.
        SUBMIT rm07docs USING SELECTION-SCREEN 1000
          WITH matnr = wa_i-matnr
          WITH lgort = wa_i-lgort
          WITH budat IN p_erdat


           AND RETURN.
      ENDIF.
  ENDCASE.

ENDFORM.                    "user_command1
*&---------------------------------------------------------------------*
*&      Form  FRM_MODIFY
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_modify .
  l_ztsycs-tcode2_mkpf = sy-tcode.
  l_ztsycs-zname =  sy-uname.
  l_ztsycs-zerdat = sy-datum.
  l_ztsycs-cputm = sy-uzeit.
  APPEND l_ztsycs.
  LOOP AT l_ztsycs.
    SELECT SINGLE zsycs INTO l_ztsycs-zsycs FROM ztsycs WHERE tcode2_mkpf = l_ztsycs-tcode2_mkpf.
    l_ztsycs-zsycs = l_ztsycs-zsycs + 1.
    MODIFY l_ztsycs.
  ENDLOOP.
  MODIFY ztsycs FROM TABLE l_ztsycs[].
ENDFORM.                    " FRM_MODIFY
*&---------------------------------------------------------------------*
*&      Form  FRM_AUTH_CHECK
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_auth_check .
  CLEAR:zbz.
  SELECT SINGLE *  FROM agr_users WHERE uname = sy-uname AND agr_name = 'Z_AU_ZRMM051'."用户是否拥有此角色判断是否可查看价格
  IF sy-subrc = 0.
    zbz = 'X'.
  ENDIF.
ENDFORM.                    " FRM_AUTH_CHECK

3.总结

没有办法,一个表里有很多数据,每个数据下还有很多数据,这种情况只有用loop中还有loop.
如果表头和表行,只有在循环中有循环.

 类似资料: