SAP ALV 介绍以及一个简单且完整的报表快速开发

收藏作为标准用:https://juejin.cn/post/7197337416097218615

链接:https://juejin.cn/post/7197337416097218615

来源:稀土掘金 作者:SAP技术成长之路

报表程序是 ABAP 中最常开发的功能之一,其中 ALV 报表必是 ABAPER 无法避免的任务,ALV 全称 SAP LIST VIEW,是 SAP 提供的强大的数据报表显示工具。

ALV 通过标准函数来直接调用,可以节省编程时间及代码量,输出界面整齐美观,大多会调用函数(CALL Function)来呈现,并且提供用户优化接口,用户可以选择相应的字段对数据进行排序和统计,并能对输出结果进行过滤查询,按自己的需求调整各栏位顺序及格式。

下方列出部分常用 ALV function:

  1. REUSE_ALV_FIELDCATALOG_MERGE
  2. REUSE_ALV_GRID_DISPLAY:Grid 格式的 ALV
  3. REUSE_ALV_LIST_DISPLAY:LIST格式的 ALV
  4. REUSE_ALV_GRID_DISPLAY_LVC

开发 ALV 的基本流程

ALV 就是一个数据报表,基本逻辑就是"查询-取值-输出"。

两个最重要的知识点:

  1. SAP 内表处理逻辑
  2. 数据库查询逻辑

开发流程如下:

  1. 定义 ALV 所要用到的类型池:TYPE-POOLS:SLIS
  2. 定义 ALV 所要显示的数据对应的内表数据类型及内表数据对象;
  3. 常用数据类型包括:
  • data: slis_fieldcat_alv 定义要显示的字段的详细信息。
  • data: slis_t_fieldcat_alv 包含所有要显示字段信息。
  • data: i_layout

要用的参数有:

  • slis_fieldcat-col_pos = 1 : 列编号从1开始。
  • slis_fieldcat-fieldname = : 原表所在字段的名称。
  • slis_fieldcat-seltext_m = : 显示本字段名称,即新字段名称。
  • slis_fieldcat-i_fieldcat_key : 固定列, 固定 'X'
  1. 定义一些显示 ALV 时所要使用到的变量,例如:

    Data:w_repid like sy-repid, " ABAP 程序,我们一般取当前程序

  2. 定义选择屏幕

  3. 声明各个选择屏幕事件块

定义 TOP 区

复制代码
*&---------------------------------------------------------------------*  
*&  包含                ZFIUXXX_TOP  
*&---------------------------------------------------------------------*  
  
TYPE-POOLS:slis.  
TABLES: asmdt,skat,t024.  
  
DATA:BEGIN OF wa_ekgrp,  
       ekgrp TYPE t024-ekgrp,  
     END OF wa_ekgrp.  
DATA:it_ekgrp LIKE TABLE OF wa_ekgrp.  
  
DATA: BEGIN OF gs_out,  
        asnum      TYPE asmdt-asnum,    " 服务编号  
        asktx      TYPE asmdt-asktx,    " 服务文本描述  
        saknr      TYPE skat-saknr,     " 总账科目  
        txt20      TYPE skat-txt20,     " 总账科目描述  
        zekgrp_str TYPE string,         " 采购组  
        erdat      TYPE erdat,          " 创建日期  
        erzet      TYPE erzet,          " 创建时间  
        ernam      TYPE ernam,          " 创建人员  
        zlogin     TYPE zlogin,         " 登录系统ID  
        flag,  
      END OF gs_out.  
DATA: gt_out LIKE TABLE OF gs_out.  
  
DATA: gs_save LIKE gs_out,  
      gt_save LIKE gt_out.  
  
DATA: gs_out1 LIKE gs_out,  
      gt_out1 LIKE gt_out.  
  
DATA: BEGIN OF gs_ekgrp,  
        ekgrp TYPE t024-ekgrp,  " 采购组  
        eknam TYPE t024-eknam,  "采购组描述  
        sel,   " 复选框  
      END OF gs_ekgrp.  
  
DATA: gt_ekgrp LIKE TABLE OF gs_ekgrp.   " 定义参照结构体类型的内表  
  
  
DATA: gs_layout   TYPE lvc_s_layo,  
      gs_fieldcat TYPE lvc_s_fcat,  
      gt_fieldcat TYPE lvc_t_fcat,  
  
      i_layout    TYPE lvc_s_layo,  
      is_fieldcat TYPE lvc_s_fcat,  
      it_fieldcat TYPE lvc_t_fcat.  
  
DATA: gv_tabix TYPE sy-tabix.  
  
DATA:gr_grid TYPE REF TO cl_gui_alv_grid.  
DATA:gs_stbl TYPE lvc_s_stbl.  
DATA:gcl_alv_grid TYPE REF TO cl_gui_alv_grid,  
     gc_grid      TYPE REF TO cl_gui_alv_grid.  
FIELD-SYMBOLS:<f_out>  LIKE gs_out.  
  
DATA: gs_events TYPE slis_alv_event,  
      gt_events TYPE slis_t_event.  
  
DATA: c_str TYPE string.  
  
DATA: opcode_usr_attr(1) TYPE x VALUE 5,  
      terminal           TYPE usr41-terminal.  
  
***** SEREEN *****
SELECTION-SCREEN: BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.  
SELECT-OPTIONS: so_asnum FOR asmdt-asnum,  
                so_ekgrp FOR t024-ekgrp.  
SELECTION-SCREEN: END OF BLOCK b1.

定义 FORM 和模块

复制代码
*&---------------------------------------------------------------------*  
*&  INCLUDE                ZFIUXX_FO1  
*&---------------------------------------------------------------------*  
*&---------------------------------------------------------------------*  
*&      Form  GET_DATA  
*&---------------------------------------------------------------------*  
*       text  
*----------------------------------------------------------------------*  
*  -->  p1        text  
*  <--  p2        text  
*----------------------------------------------------------------------*  
FORM  get_data .  
  
  CLEAR: gs_out.  
  REFRESH: gt_out.  
  
  " 读取服务编号和描述  
  SELECT asnum  
         FROM asmd INTO CORRESPONDING FIELDS OF TABLE gt_out  
               WHERE asnum IN so_asnum AND lvorm = ''.  
  
  SORT gt_out BY asnum.                   " 先排序,再去除重复  
*  DELETE gt_out WHERE asnum IS INITIAL.   " 删除空格  
*  DELETE ADJACENT DUPLICATES FROM gt_out COMPARING asnum.  
  
  LOOP AT gt_out INTO gs_out.  
  
    SELECT SINGLE asktx FROM asmdt INTO gs_out-asktx  
           WHERE asnum = gs_out-asnum  
           AND spras = sy-langu.  
  
    SELECT SINGLE saknr  
           txt20  
           zekgrp_str  
           erdat  
           erzet  
           ernam  
           zlogin  
  
      FROM zfit028 INTO ( gs_out-saknr,  
                          gs_out-txt20,  
                          gs_out-zekgrp_str,  
                          gs_out-erdat,  
                          gs_out-erzet,  
                          gs_out-ernam,  
                          gs_out-zlogin )  
      WHERE asnum = gs_out-asnum.  
  
    IF gs_out-zekgrp_str IS NOT INITIAL.  
  
      REFRESH it_ekgrp.  
      SPLIT gs_out-zekgrp_str AT '/' INTO TABLE it_ekgrp.  
  
      CLEAR:wa_ekgrp.  
      LOOP AT it_ekgrp INTO wa_ekgrp.  
        IF wa_ekgrp-ekgrp IN so_ekgrp.  
          gs_out-flag = 'X'.  
          EXIT.  
        ENDIF.  
      ENDLOOP.  
    ENDIF.  
  
    IF gs_out-saknr IS INITIAL.  
      CLEAR gs_out-txt20.  
    ENDIF.  
  
    MODIFY gt_out FROM gs_out.  
    CLEAR: gs_out.  
  
  ENDLOOP.  
  DELETE gt_out WHERE zekgrp_str IS NOT INITIAL AND flag NE 'X'.  
  IF so_ekgrp IS NOT INITIAL.  
    DELETE gt_out WHERE zekgrp_str IS INITIAL.  
  ENDIF.  
  
ENDFORM.  
  
*&---------------------------------------------------------------------*  
*&      Form  CHECK_DATA  
*&---------------------------------------------------------------------*  
*       text  
*----------------------------------------------------------------------*  
*  -->  p1        text  
*  <--  p2        text  
*----------------------------------------------------------------------*  
FORM check_data .  
  
ENDFORM.  
  
*&---------------------------------------------------------------------*  
*&      Form  SHOW_DATA  
*&---------------------------------------------------------------------*  
*       text  
*----------------------------------------------------------------------*  
*  -->  p1        text  
*  <--  p2        text  
*----------------------------------------------------------------------*  
  
FORM show_data.  
  PERFORM frm_set_layout.  
  IF sy-langu = '1'.  
    PERFORM frm_pre_fieldcat.  
  ELSE.  
    PERFORM frm_pre_fieldcat_en.  
  ENDIF.  
  
  PERFORM frm_set_event.  
  
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'  
    EXPORTING  
      i_callback_program       = sy-repid  
      i_callback_pf_status_set = 'PF_STATUS_SET'  
      i_callback_user_command  = 'USER_COMMAND'  
      is_layout_lvc            = gs_layout  
      it_fieldcat_lvc          = gt_fieldcat  
      i_save                   = 'A'  
      it_events                = gt_events  
    TABLES  
      t_outtab                 = gt_out  
    EXCEPTIONS  
      program_error            = 1  
      OTHERS                   = 2.  
  
  IF sy-subrc <> 0.  
  ENDIF.  
  
ENDFORM.  
  
FORM pf_status_set USING rt_extab TYPE slis_t_extab.  
  SET PF-STATUS 'ZSTATUS'.  
ENDFORM.  
  
FORM user_command USING s_ucomm TYPE sy-ucomm  
      re_selfield TYPE slis_selfield.  
  
  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'  
    IMPORTING  
      e_grid = gr_grid.  
  CALL METHOD gr_grid->check_changed_data.  
  
  CASE s_ucomm.  
    WHEN 'BACK'.  
      LEAVE TO SCREEN 0.  
    WHEN 'SAVE'.  
      PERFORM frm_save.  
      re_selfield-refresh = 'X'.  
    WHEN '&IC1'.  
      CLEAR:gv_tabix.  
      gv_tabix = re_selfield-tabindex.  
      CLEAR:gs_out.  
      READ TABLE gt_out INTO gs_out INDEX re_selfield-tabindex .  
      CASE re_selfield-fieldname.  
        WHEN 'ZEKGRP_STR' .    " 双击采购组  
          PERFORM get_ekgrp.  
          PERFORM display_ekgrp.  
      ENDCASE.  
  
    WHEN OTHERS.  
  ENDCASE.  
ENDFORM.  
  
FORM frm_set_layout.  
  gs_layout-zebra = 'X'.  
  gs_layout-cwidth_opt = 'X'.  
  gs_layout-sel_mode = 'A'.  
ENDFORM.  
  
  
FORM frm_pre_fieldcat.  
  DATA: l_pos TYPE i.  
  CLEAR: l_pos.  
  REFRESH: gt_fieldcat.  
  
  CLEAR gs_fieldcat.  
  l_pos = l_pos + 1.  
  gs_fieldcat-col_pos = l_pos.  
  gs_fieldcat-fieldname = 'ASNUM'.  
  gs_fieldcat-coltext = '服务编号'.  
  gs_fieldcat-no_zero = 'X'.  
  APPEND gs_fieldcat TO gt_fieldcat.  
  
  CLEAR gs_fieldcat.  
  l_pos = l_pos + 1.  
  gs_fieldcat-col_pos = l_pos.  
  gs_fieldcat-fieldname = 'ASKTX'.  
  gs_fieldcat-coltext = '服务文本描述'.  
  gs_fieldcat-just = 'C'.  
  APPEND gs_fieldcat TO gt_fieldcat.  
  
  CLEAR gs_fieldcat.  
  l_pos = l_pos + 1.  
  gs_fieldcat-col_pos = l_pos.  
  gs_fieldcat-fieldname = 'SAKNR'.  
  gs_fieldcat-coltext = '总账科目'.  
  gs_fieldcat-ref_table = 'SKA1'.  
  gs_fieldcat-ref_field = 'SAKNR'.  
  gs_fieldcat-edit = 'X'.  
  APPEND gs_fieldcat TO gt_fieldcat.  
  
  CLEAR gs_fieldcat.  
  l_pos = l_pos + 1.  
  gs_fieldcat-col_pos = l_pos.  
  gs_fieldcat-fieldname = 'TXT20'.  
  gs_fieldcat-coltext = '总账科目描述'.  
  APPEND gs_fieldcat TO gt_fieldcat.  
  
  CLEAR gs_fieldcat.  
  l_pos = l_pos + 1.  
  gs_fieldcat-col_pos = l_pos.  
  gs_fieldcat-fieldname = 'ZEKGRP_STR'.  
  gs_fieldcat-coltext = '采购组'.  
  gs_fieldcat-hotspot = 'X'.  
  gs_fieldcat-emphasize = 'C001'.  
  APPEND gs_fieldcat TO gt_fieldcat.  
  
*  CLEAR gs_fieldcat.  
*  l_pos = l_pos + 1.  
*  gs_fieldcat-col_pos = l_pos.  
*  gs_fieldcat-fieldname = 'EKNAM'.  
*  gs_fieldcat-coltext = '采购组描述'.  
*  APPEND gs_fieldcat TO gt_fieldcat.  
ENDFORM.  
  
*&---------------------------------------------------------------------*  
*&      Form  FRM_SAVE  
*&---------------------------------------------------------------------*  
*       text  
*----------------------------------------------------------------------*  
*  -->  p1        text  
*  <--  p2        text  
*----------------------------------------------------------------------*  
FORM frm_save .  
  DATA: ls_zfit028 TYPE zfit028,  
        lt_zfit028 TYPE TABLE OF zfit028.  
  
  CLEAR: ls_zfit028.  
  REFRESH: lt_zfit028.  
  
  LOOP AT gt_out INTO gs_out.  
  
    MOVE gs_out-asnum TO ls_zfit028-asnum.  
    MOVE gs_out-asktx TO ls_zfit028-asktx.  
    MOVE gs_out-saknr TO ls_zfit028-saknr.  
    MOVE gs_out-txt20 TO ls_zfit028-txt20.  
    MOVE gs_out-zekgrp_str TO ls_zfit028-zekgrp_str.  
    MOVE gs_out-erdat TO ls_zfit028-erdat.  
    MOVE gs_out-erzet TO ls_zfit028-erzet.  
    MOVE gs_out-ernam TO ls_zfit028-ernam.  
    MOVE gs_out-zlogin TO ls_zfit028-zlogin.  
    APPEND ls_zfit028 TO lt_zfit028.  
  
*    MOVE-CORRESPONDING gs_out TO ls_zfit028.  
*    APPEND ls_zfit028 TO lt_zfit028.  
  
    CLEAR: gs_out,  
           ls_zfit028.  
  ENDLOOP.  
  
  
  IF lt_zfit028 IS NOT INITIAL.  
*    DELETE FROM zfit028.  
  
    MODIFY zfit028 FROM TABLE lt_zfit028.  
  
    IF sy-subrc = 0.  
      COMMIT WORK AND WAIT.  
      MESSAGE '保存成功!' TYPE 'S'.  
  
    ELSE.  
      ROLLBACK WORK.  
      MESSAGE '保存失败!' TYPE 'E'.  
    ENDIF.  
  ENDIF.  
ENDFORM.  
*&---------------------------------------------------------------------*  
*&      Form  GET_EKGRP  
*&---------------------------------------------------------------------*  
*       text  
*----------------------------------------------------------------------*  
*  -->  p1        text  
*  <--  p2        text  
*----------------------------------------------------------------------*  
FORM get_ekgrp.  
  
  DATA: lt_ekgrp LIKE gt_ekgrp,  
        ls_ekgrp LIKE gs_ekgrp.  
  
  REFRESH:gt_ekgrp.  
  
  IF gt_ekgrp IS INITIAL.  
    SELECT ekgrp  
           eknam FROM t024 INTO CORRESPONDING FIELDS OF TABLE gt_ekgrp.  
  
    MODIFY gt_ekgrp FROM gs_ekgrp TRANSPORTING sel WHERE sel EQ space.  
  ENDIF.  
  
  CLEAR: gs_out.  
  READ TABLE gt_out INTO gs_out INDEX gv_tabix.  
  IF gs_out-zekgrp_str NE ''.  
    SPLIT gs_out-zekgrp_str AT '/' INTO TABLE lt_ekgrp.  
  
    LOOP AT gt_ekgrp INTO gs_ekgrp.  
      CLEAR:ls_ekgrp.  
      READ TABLE lt_ekgrp INTO ls_ekgrp WITH KEY ekgrp = gs_ekgrp-ekgrp.  
  
      IF sy-subrc = 0.  
        gs_ekgrp-sel = 'X'.  
      ELSE.  
        gs_ekgrp-sel = ''.  
      ENDIF.  
  
      MODIFY gt_ekgrp FROM gs_ekgrp TRANSPORTING sel.  
      CLEAR: ls_ekgrp,  
             gs_ekgrp.  
    ENDLOOP.  
  ENDIF.  
  
ENDFORM.  
*&---------------------------------------------------------------------*  
*&      Form  DISPLAY_EKGRP  
*&---------------------------------------------------------------------*  
*       text  
*----------------------------------------------------------------------*  
*  -->  p1        text  
*  <--  p2        text  
*----------------------------------------------------------------------*  
FORM display_ekgrp.  
  
  DATA lv_grid_title TYPE lvc_title.  
  
  IF sy-langu = '1'.  
    PERFORM frm_i_fieldcat.  
    lv_grid_title = '采购组选择'.  
  ELSE.  
    PERFORM frm_i_fieldcat_en.  
    lv_grid_title = 'Purchase Group Select'.  
  ENDIF.  
  
  PERFORM frm_i_setlayout.  
*  gs_glay-edt_cll_cb = 'X'.  
  
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'  
    EXPORTING  
      i_callback_program       = sy-repid  
      i_grid_title             = lv_grid_title  
      i_callback_pf_status_set = 'PF_STATUS_SET1'  
      i_callback_user_command  = 'USER_COMMAND1'  
      is_layout_lvc            = i_layout  
      it_fieldcat_lvc          = it_fieldcat  
    TABLES  
      t_outtab                 = gt_ekgrp  
    EXCEPTIONS  
      program_error            = 1  
      OTHERS                   = 2.  
  
  IF sy-subrc <> 0.  
  ENDIF.  
ENDFORM.  
  
FORM frm_i_setlayout.  
  i_layout-zebra = 'X'.  
  i_layout-sel_mode = 'A'.  
  i_layout-cwidth_opt = 'X'.  
ENDFORM.  
  
FORM pf_status_set1 USING rt_extab TYPE slis_t_extab.  
  SET PF-STATUS 'ZSTATUS1'.  
ENDFORM.  
  
FORM user_command1 USING s_ucomm TYPE sy-ucomm  
      re_selfield TYPE slis_selfield.  
  
  DATA: lr_grid TYPE REF TO cl_gui_alv_grid.  
  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'  
    IMPORTING  
      e_grid = lr_grid.  
  CALL METHOD lr_grid->check_changed_data.  
  
  CASE s_ucomm.  
    WHEN 'BACK' OR 'CANCEL'.  
      LEAVE TO SCREEN 0.  
  
    WHEN 'SEL_ALL'.  
      PERFORM frm_sel_all.  
      re_selfield-refresh = 'X'.  
  
    WHEN 'DESEL_ALL'.  
      PERFORM frm_desel_all.  
      re_selfield-refresh = 'X'.  
  
    WHEN 'SAVE'.  
      PERFORM frm_save1.  
      re_selfield-refresh = 'X'.  
    WHEN OTHERS.  
  ENDCASE.  
ENDFORM.  
  
FORM frm_i_fieldcat.  
  DATA: l_pos TYPE i.  
  CLEAR: l_pos.  
  REFRESH: it_fieldcat.  
  
  CLEAR is_fieldcat.  
  l_pos = l_pos + 1.  
  is_fieldcat-col_pos = l_pos.  
  is_fieldcat-fieldname = 'SEL'.  
  is_fieldcat-coltext = '选择框'.  
  is_fieldcat-checkbox = 'X'.  
  is_fieldcat-edit = 'X'.  
  APPEND is_fieldcat TO it_fieldcat.  
  
  CLEAR is_fieldcat.  
  l_pos = l_pos + 1.  
  is_fieldcat-col_pos = l_pos.  
  is_fieldcat-fieldname = 'EKGRP'.  
  is_fieldcat-coltext = '采购组'.  
  is_fieldcat-ref_table = 'T024'.  
  is_fieldcat-ref_field = 'EKGRP'.  
  APPEND is_fieldcat TO it_fieldcat.  
  
  CLEAR is_fieldcat.  
  l_pos = l_pos + 1.  
  is_fieldcat-col_pos = l_pos.  
  is_fieldcat-fieldname = 'EKNAM'.  
  is_fieldcat-coltext = '采购组描述'.  
  APPEND is_fieldcat TO it_fieldcat.  
  
ENDFORM.  
*&---------------------------------------------------------------------*  
*&      Form  FRM_SAVE1  
*&---------------------------------------------------------------------*  
*       text  
*----------------------------------------------------------------------*  
*  -->  p1        text  
*  <--  p2        text  
*----------------------------------------------------------------------*  
FORM frm_save1.  
  
  IF gt_ekgrp IS NOT INITIAL.  
    PERFORM get_data1.  
  ENDIF.  
  
  IF gr_grid IS  NOT INITIAL.  
    CALL METHOD gr_grid->refresh_table_display.  
  ENDIF.  
  
  LEAVE TO SCREEN 0.  
  
ENDFORM.  
*&---------------------------------------------------------------------*  
*&      Form  GET_DATA1  
*&---------------------------------------------------------------------*  
*       text  
*----------------------------------------------------------------------*  
*  -->  p1        text  
*  <--  p2        text  
*----------------------------------------------------------------------*  
FORM get_data1 .  
  
  DATA: lv_ekgrp TYPE string.  
  CLEAR:lv_ekgrp.  
  
  FIELD-SYMBOLS:<fs_out1> LIKE gs_out.  
  
  LOOP AT gt_ekgrp INTO gs_ekgrp WHERE sel = 'X'  .  
    CONCATENATE lv_ekgrp gs_ekgrp-ekgrp INTO lv_ekgrp SEPARATED BY '/'.  
  
    CLEAR:gs_ekgrp.  
  ENDLOOP.  
  
  SHIFT lv_ekgrp LEFT DELETING LEADING '/'.  
  
  UNASSIGN <fs_out1>.  
  READ TABLE gt_out ASSIGNING <fs_out1> INDEX gv_tabix.  
  
  IF sy-subrc = 0.  
    <fs_out1>-zekgrp_str = lv_ekgrp.  
  ENDIF.  
  
  " 显示当前登录id  
  CALL METHOD cl_gui_frontend_services=>get_user_name  
    CHANGING  
      user_name            = c_str  
    EXCEPTIONS  
      cntl_error           = 1  
      error_no_gui         = 2  
      not_supported_by_gui = 3  
      OTHERS               = 4.  
  
  CALL METHOD cl_gui_cfw=>flush  
    EXCEPTIONS  
      cntl_system_error = 1  
      cntl_error        = 2.  
  
  CALL 'ThUsrInfo' ID 'OPCODE' FIELD opcode_usr_attr  
  ID'TERMINAL' FIELD terminal.  
  
  <fs_out1>-erdat = sy-datum.  
  <fs_out1>-erzet = sy-uzeit.  
  <fs_out1>-ernam = c_str.  
  <fs_out1>-zlogin = terminal.  
  
ENDFORM.  
*&---------------------------------------------------------------------*  
*&      Form  FRM_SEL_ALL  
*&---------------------------------------------------------------------*  
*       text  
*----------------------------------------------------------------------*  
*  -->  p1        text  
*  <--  p2        text  
*----------------------------------------------------------------------*  
FORM frm_sel_all .  
  gs_ekgrp-sel = 'X'.  
  MODIFY gt_ekgrp FROM gs_ekgrp TRANSPORTING sel WHERE sel EQ space.  
ENDFORM.  
*&---------------------------------------------------------------------*  
*&      Form  FRM_DESEL_ALL  
*&---------------------------------------------------------------------*  
*       text  
*----------------------------------------------------------------------*  
*  -->  p1        text  
*  <--  p2        text  
*----------------------------------------------------------------------*  
FORM frm_desel_all .  
  gs_ekgrp-sel = ''.  
  MODIFY gt_ekgrp FROM gs_ekgrp TRANSPORTING sel WHERE sel EQ 'X'.  
ENDFORM.  
*&---------------------------------------------------------------------*  
*&      Form  FRM_PRE_FIELDCAT_EN  
*&---------------------------------------------------------------------*  
*       text  
*----------------------------------------------------------------------*  
*  -->  p1        text  
*  <--  p2        text  
*----------------------------------------------------------------------*  
FORM frm_pre_fieldcat_en .  
  DATA: l_pos TYPE i.  
  CLEAR: l_pos.  
  REFRESH: gt_fieldcat.  
  
  CLEAR gs_fieldcat.  
  l_pos = l_pos + 1.  
  gs_fieldcat-col_pos = l_pos.  
  gs_fieldcat-fieldname = 'ASNUM'.  
  gs_fieldcat-coltext = 'Activity number'.  
  gs_fieldcat-no_zero = 'X'.  
  APPEND gs_fieldcat TO gt_fieldcat.  
  
  CLEAR gs_fieldcat.  
  l_pos = l_pos + 1.  
  gs_fieldcat-col_pos = l_pos.  
  gs_fieldcat-fieldname = 'ASKTX'.  
  gs_fieldcat-coltext = 'Activity number name'.  
  gs_fieldcat-just = 'C'.  
  APPEND gs_fieldcat TO gt_fieldcat.  
  
  CLEAR gs_fieldcat.  
  l_pos = l_pos + 1.  
  gs_fieldcat-col_pos = l_pos.  
  gs_fieldcat-fieldname = 'SAKNR'.  
  gs_fieldcat-coltext = 'G/L account number'.  
  gs_fieldcat-ref_table = 'SKA1'.  
  gs_fieldcat-ref_field = 'SAKNR'.  
  gs_fieldcat-edit = 'X'.  
  APPEND gs_fieldcat TO gt_fieldcat.  
  
  CLEAR gs_fieldcat.  
  l_pos = l_pos + 1.  
  gs_fieldcat-col_pos = l_pos.  
  gs_fieldcat-fieldname = 'TXT20'.  
  gs_fieldcat-coltext = 'G/L account number name'.  
  APPEND gs_fieldcat TO gt_fieldcat.  
  
  CLEAR gs_fieldcat.  
  l_pos = l_pos + 1.  
  gs_fieldcat-col_pos = l_pos.  
  gs_fieldcat-fieldname = 'ZEKGRP_STR'.  
  gs_fieldcat-coltext = 'Purchase group'.  
  gs_fieldcat-hotspot = 'X'.  
  gs_fieldcat-emphasize = 'C001'.  
  APPEND gs_fieldcat TO gt_fieldcat.  
ENDFORM.  
*&---------------------------------------------------------------------*  
*&      Form  FRM_I_FIELDCAT_EN  
*&---------------------------------------------------------------------*  
*       text  
*----------------------------------------------------------------------*  
*  -->  p1        text  
*  <--  p2        text  
*----------------------------------------------------------------------*  
FORM frm_i_fieldcat_en .  
  DATA: l_pos TYPE i.  
  CLEAR: l_pos.  
  REFRESH: it_fieldcat.  
  
  CLEAR is_fieldcat.  
  l_pos = l_pos + 1.  
  is_fieldcat-col_pos = l_pos.  
  is_fieldcat-fieldname = 'SEL'.  
  is_fieldcat-coltext = 'Select'.  
  is_fieldcat-checkbox = 'X'.  
  is_fieldcat-edit = 'X'.  
  APPEND is_fieldcat TO it_fieldcat.  
  
  CLEAR is_fieldcat.  
  l_pos = l_pos + 1.  
  is_fieldcat-col_pos = l_pos.  
  is_fieldcat-fieldname = 'EKGRP'.  
  is_fieldcat-coltext = 'Purchase Group'.  
  is_fieldcat-ref_table = 'T024'.  
  is_fieldcat-ref_field = 'EKGRP'.  
  APPEND is_fieldcat TO it_fieldcat.  
  
  CLEAR is_fieldcat.  
  l_pos = l_pos + 1.  
  is_fieldcat-col_pos = l_pos.  
  is_fieldcat-fieldname = 'EKNAM'.  
  is_fieldcat-coltext = 'Purchase Group Name'.  
  APPEND is_fieldcat TO it_fieldcat.  
ENDFORM.

事件区定义

复制代码
*&---------------------------------------------------------------------*  
*&  包含                ZFIUXXX_LCL  
*&---------------------------------------------------------------------*  
  
CLASS lcl_event_receiver DEFINITION.  " LCL_EVENT_RECEIVER DEFINITION  
  PUBLIC SECTION.  
    METHODS data_changed FOR EVENT data_changed OF cl_gui_alv_grid  
      IMPORTING er_data_changed  
                  e_ucomm.  
  
    METHODS handle_modify  
                  FOR EVENT data_changed_finished OF cl_gui_alv_grid  
      IMPORTING e_modified et_good_cells.  
ENDCLASS.  
  
  
CLASS lcl_event_receiver IMPLEMENTATION.  
  METHOD data_changed.  
    PERFORM handle_data_changed USING er_data_changed.  
  ENDMETHOD.  
  
  METHOD handle_modify.  
    PERFORM handle_data_finish USING e_modified et_good_cells.  
  ENDMETHOD.    " HANDLE MODIFY  
  
ENDCLASS.         " LCL_EVENT RECEIVER IMPLEMENTATION  
  
  
*&---------------------------------------------------------------------*  
*&      Form  HANDLE_DATA_CHANGED  
*&---------------------------------------------------------------------*  
*       text  
*----------------------------------------------------------------------*  
*      -->P_ER_DATA_CHANGED  text  
*----------------------------------------------------------------------*  
FORM handle_data_changed  USING    p_er_data_changed  
                          TYPE REF TO cl_alv_changed_data_protocol.  
  
  DATA: mod_data        TYPE lvc_t_modi,  
        gs_out_mod_data TYPE lvc_s_modi.  
  
  mod_data = p_er_data_changed->mt_mod_cells.  
  LOOP AT mod_data INTO gs_out_mod_data.  
  
  ENDLOOP.  
  
ENDFORM.  
  
  
*&---------------------------------------------------------------------*  
*&      Form  HANDLE_DATA_FINISH  
*&---------------------------------------------------------------------*  
*       text  
*----------------------------------------------------------------------*  
*      -->P_E_MODIFIED  text  
*      -->P_ET_GOOD_CELLS  text  
*----------------------------------------------------------------------*  
FORM handle_data_finish  USING    e_modified TYPE char01  
                                  et_good_cells TYPE lvc_t_modi.  
  
  DATA: eh_good_cells TYPE lvc_s_modi.  
  
  IF e_modified = 'X'.  
    LOOP AT et_good_cells INTO eh_good_cells.      " 修改的行  
      UNASSIGN: <f_out>.  
      READ TABLE gt_out ASSIGNING <f_out> INDEX eh_good_cells-row_id.  
      IF sy-subrc = 0.  
  
        CLEAR: gs_out.  
        LOOP AT gt_out INTO gs_out WHERE asnum = <f_out>-asnum.  
          " 显示当前登录id  
          CALL METHOD cl_gui_frontend_services=>get_user_name  
            CHANGING  
              user_name            = c_str  
            EXCEPTIONS  
              cntl_error           = 1  
              error_no_gui         = 2  
              not_supported_by_gui = 3  
              OTHERS               = 4.  
  
          CALL METHOD cl_gui_cfw=>flush  
            EXCEPTIONS  
              cntl_system_error = 1  
              cntl_error        = 2.  
  
          CALL 'ThUsrInfo' ID 'OPCODE' FIELD opcode_usr_attr  
          ID'TERMINAL' FIELD terminal.  
  
          gs_out-erdat = sy-datum.  
          gs_out-erzet = sy-uzeit.  
          gs_out-ernam = c_str.  
          gs_out-zlogin = terminal.  
          CASE eh_good_cells-fieldname.  
  
            WHEN 'SAKNR'.  " 手动更新SAKNR  
  
              SELECT COUNT( * ) FROM skat WHERE saknr = <f_out>-saknr.  
              IF sy-subrc = 0.  
                SELECT SINGLE txt20  
                FROM skat  
                INTO gs_out-txt20  
                WHERE saknr = <f_out>-saknr AND spras = sy-langu.  
  
                IF sy-subrc NE 0.  
                  CLEAR: gs_out-txt20." ,gs_out-erdat,gs_out-erzet,gs_out-ernam,gs_out-zlogin.  
                ENDIF.  
                MODIFY gt_out FROM gs_out TRANSPORTING txt20 erdat erzet ernam zlogin .  
                CLEAR: gs_out.  
              ELSE.  
                MESSAGE '输入的总账科目有误,请检查!' TYPE 'E'.  
              ENDIF.  
  
  
  
            WHEN 'ZEKGRP_STR'.  
  
              IF sy-subrc NE 0.  
                CLEAR: gs_out-zekgrp_str.  
              ENDIF.  
  
              MODIFY gt_out FROM gs_out TRANSPORTING zekgrp_str erdat erzet ernam zlogin.  
              CLEAR: gs_out.  
  
            WHEN OTHERS.  
          ENDCASE.  
        ENDLOOP.  
      ENDIF.  
    ENDLOOP.  
  
    " 稳定刷新  
    gs_stbl-row = 'X'.  
    gs_stbl-col = 'X'.  
    CALL METHOD gcl_alv_grid->refresh_table_display  
      EXPORTING  
        is_stable = gs_stbl.  
  ENDIF.  
ENDFORM.  
  
  
*&---------------------------------------------------------------------*  
*&      Form  REFRESH_TABLE_ALV  
*&---------------------------------------------------------------------*  
*       text  
*----------------------------------------------------------------------*  
*  -->  p1        text  
*  <--  p2        text  
*----------------------------------------------------------------------*  
FORM refresh_table_alv .  
  gs_stbl = 'X'. " 基于行的稳定刷新  
  gs_stbl = 'X'.  " 基于列稳定刷新  
  CALL METHOD gcl_alv_grid->refresh_table_display  
    EXPORTING  
      is_stable = gs_stbl.  
ENDFORM.  
  
*&---------------------------------------------------------------------*  
*&      Form  FRM_SET_EVENT  
*定义事件  
*&---------------------------------------------------------------------*  
FORM frm_set_event.  
  CALL FUNCTION 'REUSE_ALV_EVENTS_GET'  
    EXPORTING  
      i_list_type     = 0  
    IMPORTING  
      et_events       = gt_events  
    EXCEPTIONS  
      list_type_wrong = 1  
      OTHERS          = 2.  
  
  IF sy-subrc <> 0.  
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno  
    WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.  
  ENDIF.  
  
  gs_events-name = 'CALLER_EXIT'.  
  gs_events-form = 'FRM_CALLER_EXIT'.  
  APPEND gs_events TO gt_events.  
  
ENDFORM.    " FRM_SET_EVENT  
  
  
*&---------------------------------------------------------------------*  
*&      Form  F_CALLER_EXIT  
* 注册回车事件  
*&---------------------------------------------------------------------*  
FORM frm_caller_exit USING ls_data TYPE slis_data_caller_exit.  
  
  DATA gt_event_receiver TYPE REF TO lcl_event_receiver.  
  DATA: lt_f4 TYPE lvc_t_f4,  
        ls_f4 TYPE lvc_s_f4.  
  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'  
    IMPORTING  
      e_grid = gcl_alv_grid.  
  
* 设置enter事件  
  CALL METHOD gcl_alv_grid->register_edit_event  
    EXPORTING  
      i_event_id = cl_gui_alv_grid=>mc_evt_enter  
    EXCEPTIONS  
      error      = 1  
      OTHERS     = 2.  
  CALL METHOD gcl_alv_grid->register_edit_event  
    EXPORTING  
      i_event_id = cl_gui_alv_grid=>mc_evt_modified  
    EXCEPTIONS  
      error      = 1  
      OTHERS     = 2.  
  IF sy-subrc <> 0.  
*   Implement suGT_OUTle error handling here  
  ENDIF.  
  
  CREATE OBJECT gt_event_receiver.  
  SET HANDLER gt_event_receiver->handle_modify FOR gcl_alv_grid.  
  SET HANDLER gt_event_receiver->data_changed FOR gcl_alv_grid.  
  
ENDFORM.                   "F_CALLER_EXIT

主程序

复制代码
*&---------------------------------------------------------------------*
*& Report ZFIUXXX
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zfiuxxx.

INCLUDE zfiuxxx_top.    " Global Data
INCLUDE zfiuxxx_fo1.    " Function Modules
INCLUDE zfiuxxx_lcl.    " Events

START-OF-SELECTION.

  PERFORM get_data.
  PERFORM check_data.
  PERFORM show_data.

最终呈现:

相关推荐
山茶花开时。1 天前
[SAP ABAP] CONVERSION_EXIT_ALPHA_INPUT
sap·abap
EasyStudios3 天前
金色传说:SAP-ABAP-Excel数据导入工具函数示例
sap·abap·excel导入
EasyStudios3 天前
金色传说:SAP-ABAP-交货单创建及过账工具类示例
sap·abap·工具类·se24·交货单bapi
goyeer6 天前
05.[SAP ABAP] ABAP中的运算符
算法·sap·abap·运算符
爱喝水的鱼丶20 天前
SAP-ABAP:SAP概述:数据处理的系统、应用与产品
运维·学习·sap·abap·1024程序员节
IT小白农民工24 天前
安装SAP Business one for HANA之前的准备
linux·经验分享·sap
寒武青锋24 天前
SAP 后台批量激活程序
sap·abap
LilySesy1 个月前
ABAP+在select的时候,可以A=B A=C B=C这样子JOIN吗?
数据库·sql·ai·excel·sap·abap
LilySesy1 个月前
ABAP+WHERE字段长度不一致报错解决
java·前端·javascript·bug·sap·abap·alv