SAP ABAP实现ALV两栏式程序开发(案例)

        本文以如下财务的收款认领平台为例,来展示一个常规的ALV两栏式报表程序的开发,案例图如下:   

        实现的大概逻辑是:首先定制一个屏幕容器,然后在定制屏幕中存放子容器来分别显示两栏ALV报表。最终实现了一个上栏是主数据,下栏可以通过点击热键显示某条主数据的详情数据。

        一、首先是程序代码,准备数据和最重要的新建屏幕      

        二、新建一个通常屏幕内容如下:

        全局定义参数:

DATA: go_toolbar       TYPE REF TO cl_gui_toolbar,
      go_dragdrop_alv  TYPE REF TO cl_dragdrop,
      go_container     TYPE REF TO cl_gui_custom_container,
      go_container_d   TYPE REF TO cl_gui_docking_container,
      go_container_s   TYPE REF TO cl_gui_docking_container,
      gs_layo_detial   TYPE lvc_s_layo,
      gs_layo_data     TYPE lvc_s_layo,
      gs_layo_data_dis TYPE lvc_s_layo,
      gs_fcat_detial   TYPE lvc_s_fcat,
      gt_fcat_detial   TYPE lvc_t_fcat,
      gs_fcat_data     TYPE lvc_s_fcat,
      gt_fcat_data     TYPE lvc_t_fcat,
      gs_fcat_data_dis TYPE lvc_s_fcat,
      gt_fcat_data_dis TYPE lvc_t_fcat,
      go_grid_detial   TYPE REF TO cl_gui_alv_grid,
      go_grid_data_dis TYPE REF TO cl_gui_alv_grid,
      go_grid_data     TYPE REF TO cl_gui_alv_grid.

        2.1 状态栏和返回退出功能

        (1)GUI STATUS

MODULE status_9000 OUTPUT.
  SET PF-STATUS 'STATUS2'.
  SET TITLEBAR 'ZTIT'.
ENDMODULE.

         (2)exit 注意要设置功能类型为E才能生效,如下图

MODULE exit_0100 INPUT.
  LEAVE TO SCREEN 0.
ENDMODULE.

        (3)创建容器

FORM create_container .
  IF go_container IS INITIAL.
    CREATE OBJECT go_container
      EXPORTING
        container_name = 'CTRL_CONTAINER'."定制屏幕名
  ENDIF.
ENDFORM.

        (4)user_command

FORM user_command_9000 .
  CLEAR: gv_code.
  gv_code = ok_code.
  CLEAR: ok_code.

  go_grid_detial->check_changed_data( ).
  go_grid_data->check_changed_data( ).

  CASE gv_code.
    WHEN '&IC1'."双击
    WHEN '&DATA_SAVE'."保存数据存底表
      PERFORM frm_save_data.
    WHEN 'CONFIRM'."确认收款
      PERFORM frm_confirm_data.
    WHEN 'DISCON'."拆行
      PERFORM frm_disconnect_data.
    WHEN 'YSFL'. "确认预收并返利
      PERFORM frm_ysfl_data.
    WHEN 'CHARGE'."冲销收款认领
      PERFORM frm_charge_data.
    WHEN 'SAVE'."明细确认
      PERFORM frm_detail_data_confirm.
  ENDCASE.

  CLEAR: gv_code.
ENDFORM.

        2.2主数据界面逻辑        

FORM display_data .
  IF go_grid_data IS INITIAL.
    CREATE OBJECT go_grid_data
      EXPORTING
        i_parent = go_container.

    PERFORM set_alv_drag_data.      "设置GRAG
    PERFORM set_layo_data.          "格式设置
    PERFORM set_fcat_data.          "设置列属性
    PERFORM register_event_data.    "注册事件
    PERFORM alv_first_display_data.  "ALV显示
  ELSE.
    PERFORM refresh_table_display USING go_grid_data.
  ENDIF.
ENDFORM.
FORM set_alv_drag_data .
  DATA lv_effect TYPE i .

  lv_effect = cl_dragdrop=>move + cl_dragdrop=>copy .

  CREATE OBJECT go_dragdrop_alv.

  CALL METHOD go_dragdrop_alv->add
    EXPORTING
      flavor     = 'LINE'
      dragsrc    = 'X'
      droptarget = ''
      effect     = lv_effect.

  go_dragdrop_alv->get_handle( IMPORTING handle = gv_node_dragdropid_d ).
ENDFORM.
FORM set_layo_data .
  CLEAR: gs_layo_data.
  gs_layo_data-zebra      = 'X'.
  gs_layo_data-cwidth_opt = 'X'.
  gs_layo_data-sel_mode   = 'D'.
  gs_layo_data-s_dragdrop-row_ddid = gv_node_dragdropid_d.

ENDFORM.
FORM set_fcat_data .
  DEFINE set_fieldcat2.
    CLEAR gs_fcat_data.
    gs_fcat_data-fieldname = &1.
    gs_fcat_data-scrtext_l = &2.
    gs_fcat_data-ref_field = &3.
    gs_fcat_data-ref_table = &4.
    gs_fcat_data-key = &5.
    gs_fcat_data-edit = &6.
    gs_fcat_data-hotspot = &7.
    gs_fcat_data-datatype = &8.
    gs_fcat_data-outputlen = &9.

    APPEND gs_fcat_data TO gt_fcat_data.
  END-OF-DEFINITION.

  REFRESH: gt_fcat_data.

  set_fieldcat2 'ID' '检查状态' '' '' '' '' '' ''  18.
  set_fieldcat2 'MSG' '错误信息' '' '' '' '' '' ''  18.
  set_fieldcat2 'ZLSM' '银行流水编码' '' '' '' '' '' ''  18.
  set_fieldcat2 'ZCHXM' '拆分行项目' '' '' '' '' '' ''  18.

ENDFORM.
FORM register_event_data .
  IF go_event_handler IS INITIAL.
    CREATE OBJECT go_event_handler.
  ENDIF.

  CALL METHOD go_grid_data->register_edit_event
    EXPORTING
      i_event_id = cl_gui_alv_grid=>mc_evt_modified.

  CALL METHOD go_grid_data->register_edit_event
    EXPORTING
      i_event_id = cl_gui_alv_grid=>mc_evt_enter.

  SET HANDLER go_event_handler->handle_data_changed           FOR go_grid_data.
  SET HANDLER go_event_handler->handle_toolbar                FOR go_grid_data.
  SET HANDLER go_event_handler->handle_hotspot                FOR go_grid_data.
  SET HANDLER go_event_handler->handle_user_command           FOR go_grid_data.
  SET HANDLER go_event_handler->handle_after_user_command     FOR go_grid_data.
ENDFORM.
FORM alv_first_display_data .
  DATA: ls_variant TYPE  disvariant.

  ls_variant-report = sy-repid.
  ls_variant-username = sy-uname.
  ls_variant-handle = '1'.

  CALL METHOD go_grid_data->set_table_for_first_display
    EXPORTING
      is_variant      = ls_variant
      i_save          = 'A'
      i_default       = 'X'
      is_layout       = gs_layo_data
    CHANGING
      it_fieldcatalog = gt_fcat_data
      it_outtab       = gt_main_data.
ENDFORM.
FORM refresh_table_display  USING  po_grid TYPE REF TO cl_gui_alv_grid.
  DATA: ls_stbl TYPE lvc_s_stbl .

  ls_stbl-row = 'X' .
  ls_stbl-col = 'X' .

  CHECK NOT po_grid IS INITIAL.

  "刷新LAYOUT,优化列宽
  gs_layout-cwidth_opt = 'X'.
  CALL METHOD po_grid->set_frontend_layout
    EXPORTING
      is_layout = gs_layout.

  CALL METHOD po_grid->refresh_table_display
    EXPORTING
      is_stable = ls_stbl
    EXCEPTIONS
      finished  = 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.

ENDFORM.

         注册事件:

CLASS lcl_event_handler DEFINITION.
  PUBLIC SECTION.
    METHODS:
      handle_data_changed FOR EVENT data_changed_finished OF cl_gui_alv_grid
        IMPORTING e_modified et_good_cells,

      handle_toolbar
        FOR EVENT toolbar OF cl_gui_alv_grid
        IMPORTING sender e_object,

      handle_after_user_command
        FOR EVENT after_user_command OF cl_gui_alv_grid
        IMPORTING sender e_ucomm,

      handle_user_command
        FOR EVENT after_user_command OF cl_gui_alv_grid
        IMPORTING sender e_ucomm,

      handle_hotspot
        FOR EVENT hotspot_click OF cl_gui_alv_grid
        IMPORTING sender e_row_id e_column_id.

ENDCLASS.
CLASS lcl_event_handler IMPLEMENTATION.
  METHOD handle_data_changed.
    PERFORM handle_data_changed ."回车事件
  ENDMETHOD.

  METHOD handle_toolbar.
    PERFORM handle_toolbar USING sender e_object. "容器工具栏事件
  ENDMETHOD.                    "handle_toolbar

  METHOD handle_hotspot.
    PERFORM hotspot_click USING sender e_row_id e_column_id."热键事件
  ENDMETHOD.                    "HANDLE_HOTSPOT

  METHOD handle_after_user_command.
    PERFORM handle_after_user_command USING sender e_ucomm.
  ENDMETHOD.    "handle_after_user_command

  METHOD handle_user_command.
    PERFORM after_user_command USING sender e_ucomm.
  ENDMETHOD.                    "HANDLE_USER_COMMAND
ENDCLASS.

DATA: go_event_handler   TYPE REF TO lcl_event_handler.
FORM handle_after_user_command USING po_sender
                                       pa_ucomm TYPE sy-ucomm.
  cl_gui_cfw=>set_new_ok_code( pa_ucomm ).
ENDFORM. " HANDLE_AFTER_USER_COMMAND
FORM after_user_command  USING  po_sender
                                pa_ucomm TYPE sy-ucomm.
  cl_gui_cfw=>set_new_ok_code( pa_ucomm ).
ENDFORM.       

        2.3 详情数据

FORM display_detail .
  IF go_grid_detial IS INITIAL.
    IF go_container_d IS INITIAL.
      CREATE OBJECT go_container_d
        EXPORTING
          side                        = cl_gui_docking_container=>dock_at_bottom  "位于下方
          extension                   = 50
        EXCEPTIONS
          cntl_error                  = 1
          cntl_system_error           = 2
          create_error                = 3
          lifetime_error              = 4
          lifetime_dynpro_dynpro_link = 5
          OTHERS                      = 6.
      IF sy-subrc <> 0.
        MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
      ENDIF.
    ENDIF.

    CREATE OBJECT go_grid_detial
      EXPORTING
        i_parent = go_container_d.

    PERFORM set_alv_drag_detial.      "设置GRAG
    PERFORM set_layo_detial.          "格式设置
    PERFORM set_fcat_detial.          "设置列属性
    PERFORM register_event_detial.   "注册事件
    PERFORM alv_first_display_detial. "ALV显示
  ELSE.
    PERFORM refresh_table_display USING go_grid_detial.
  ENDIF.

  IF r1 = 'X'.  
    CALL METHOD go_container_d->set_visible  "容器显示与否
      EXPORTING
        visible = ''.
  ELSE.
    CALL METHOD go_container_d->set_visible
      EXPORTING
        visible = 'X'.
  ENDIF.
ENDFORM.

其余逻辑通主数据界面逻辑,注意grid参数和容器参数的不同

        2.4 穿透

        至于说穿透到另外一个ALV界面的话可以用FUNCTION ALV来实现。就例如本案例的拆行功能。点击按钮后跳转到新的界面,form如下,详细代码省略,读者可以按照function alv的逻辑去写,模板可用笔者的另外一篇文章SAP ABAP常规报表开发模板_sap文档模版-CSDN博客

FORM frm_disconnect_data .
  DATA:lv_flag TYPE c1.
  DATA:lt_row   TYPE  lvc_t_roid.
  
  "获取选中行
  CALL METHOD go_grid_data->get_selected_rows(
    IMPORTING
      et_row_no = lt_row ).

  CLEAR:gs_main_data_dis,gt_main_data_dis.
  LOOP AT gt_main_data INTO gs_main_data.

    READ TABLE lt_row INTO DATA(ls_row) WITH KEY row_id = sy-tabix.
    IF sy-subrc <> 0.
      CONTINUE.
    ENDIF.

    IF gs_main_data-belnr IS NOT INITIAL AND gs_main_data-belnr1 IS INITIAL.
      MESSAGE '已认领过的数据不能拆行!' TYPE 'S' DISPLAY LIKE 'E'.
      lv_flag = 'X'.
    ENDIF.

    MOVE-CORRESPONDING gs_main_data TO gs_main_data_dis.
    APPEND gs_main_data_dis TO gt_main_data_dis.
    EXIT.
  ENDLOOP.

  CHECK lv_flag IS INITIAL.

  "添加二十条空白行
  DO 20 TIMES.
    APPEND INITIAL LINE TO gt_main_data_dis.
  ENDDO.

  CLEAR:gt_fieldcat.
  PERFORM frm_set_layout.
  PERFORM frm_set_fieldcat.
  PERFORM frm_display_alv.

ENDFORM.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值