ABAP OO-ALV 客製报表呈现

随着产业日渐成熟,客户对于需求也越来困难,ABAPER 为了生存不可避免也必须不断精进自我,而这篇文章也是自己在学习路上的一份积累。
报表程式是 ABAP 中最常开发的功能之一,其中 ALV 报表必是ABAPER 无法避免的课题,在使用者没有要求时,大多会CALL Function 来呈现,下方列出部分常用 ALV fcnction:

REUSE_ALV_FIELDCATALOG_MERGEREUSE_ALV_GRID_DISPLAYREUSE_ALV_LIST_DISPLAYREUSE_ALV_GRID_DISPLAY_LVC

然而在部分需求中,如:搜寻条件要与 ALV 报表在相同介面时,此时便须要ALV-OO 才能达成目的
实现介面如下
http://img2.58codes.com/2024/2013500885vS4WOcTw.png
http://img2.58codes.com/2024/20135008PNa1Ow7FfD.png

在开始介绍範例程式时,会运用到下方观念

Dynamic programDialog programOOP 基础概念
如想更加了解此类型程式执行方式,可以往此方向做研究。
首先先附上程式码
TOP 区
TYPE-POOLS:abap.DATA: lt_table         LIKE TABLE OF dntab,      ls_table         TYPE dntab,      d_ref            TYPE REF TO data,      lt_comp          TYPE abap_component_tab,      lt_alv_cat       TYPE TABLE OF lvc_s_fcat,      ls_alv_cat       LIKE LINE OF lt_alv_cat,      gv_noinput       TYPE c,      gv_modify        TYPE c.*----- For Dialog Program Logic flowFIELD-SYMBOLS <gv_screen_no> TYPE any ."VALUE '1000'.DATA ok_code LIKE sy-ucomm.*----- Field SymbolFIELD-SYMBOLS: <dyn_table>     TYPE STANDARD TABLE ,               <dyn_tmp_struc> TYPE any,               <dyn_wa>        TYPE any ,               <dyn_tmp_table> TYPE table.*-------- For ALVDATA: g_container           TYPE scrfname VALUE 'ALV_P',      g_container_1         TYPE scrfname VALUE 'ALV_P2',      grid1                 TYPE REF TO cl_gui_alv_grid,      grid2                 TYPE REF TO cl_gui_alv_grid,      gs_print              TYPE lvc_s_prnt,      gs_print_1            TYPE lvc_s_prnt,      gs_layout             TYPE lvc_s_layo,      gs_layout_1           TYPE lvc_s_layo,      g_custom_container_ma TYPE REF TO cl_gui_custom_container,      g_custom_container    TYPE REF TO cl_gui_custom_container,      lt_fieldcat           TYPE slis_t_fieldcat_alv WITH HEADER LINE,      ir_data_changed       TYPE REF TO cl_alv_changed_data_protocol.*----Excel openDATA: lv_rc TYPE i.DATA: lt_file_table TYPE filetable. 

**SEREEN **

SELECTION-SCREEN BEGIN OF SCREEN 1100 AS SUBSCREEN.PARAMETERS: p_tab_n  LIKE tabname .PARAMETERS: p_infile TYPE localfile DEFAULT 'C:\temp\upload.xlsx' .  SELECTION-SCREEN  BEGIN OF  BLOCK lc_2 WITH FRAME TITLE TEXT-002 .     PARAMETERS: r_ins   TYPE c RADIOBUTTON GROUP g1.     PARAMETERS: r_mod   TYPE c RADIOBUTTON GROUP g1.  SELECTION-SCREEN END OF  BLOCK lc_2.SELECTION-SCREEN END OF SCREEN 1100 .CALL SCREEN 1000.AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_infile.  CALL METHOD cl_gui_frontend_services=>file_open_dialog    EXPORTING      window_title = '打开文件'    CHANGING      file_table   = lt_file_table      rc           = lv_rc.  IF sy-subrc = 0.    READ TABLE lt_file_table INTO DATA(wa_file_table) INDEX 1.    p_infile = wa_file_table-filename.  ENDIF.

FROM and MODULE

*&---------------------------------------------------------------------**&      Form  authorization_check*&---------------------------------------------------------------------**& Begin Date  : 2021/02/02*& Author      : Kevin Yu*& Description : 权限及输入条件确认及卡控*----------------------------------------------------------------------**& Version     :*----------------------------------------------------------------------*FORM authorization_check. "  UNASSIGN <dyn_table>. "  UNASSIGN <dyn_tmp_struc>.  IF p_tab_n IS INITIAL OR p_infile IS INITIAL.     MESSAGE 'Table or Path cannot be null!!' TYPE 'I' DISPLAY LIKE 'E'.  ELSE.    SELECT SINGLE dd02l~tabname FROM dd02l INTO @DATA(lv_tabname)           WHERE dd02l~tabname EQ @p_tab_n.    IF sy-subrc EQ 0.       PERFORM get_dynamic_itab.       PERFORM excel_upload TABLES <dyn_table> .       "CHECK <dyn_table> IS NOT INITIAL.       PERFORM display_data USING <dyn_table> .       IF     r_ins EQ 'X' AND r_mod  EQ ''.       ELSEIF r_mod EQ 'X' AND r_ins  EQ ''.       ENDIF.    ELSE.      MESSAGE 'Table Not Active, Please check!!' TYPE 'I' DISPLAY LIKE 'E'.    ENDIF.  ENDIF.ENDFORM.*&---------------------------------------------------------------------**&      Form  get_dynamic_itab*&---------------------------------------------------------------------**& Begin Date  : 2021/02/02*& Author      : Kevin Yu*& Description : 依输入 TABLE 名产出对应栏位*----------------------------------------------------------------------**& Version     :*----------------------------------------------------------------------*FORM get_dynamic_itab.*取出结构字段目录CALL FUNCTION 'NAMETAB_GET'  EXPORTING    langu                     = sy-langu    tabname                   = p_tab_n  TABLES    nametab                   = lt_table.  IF sy-subrc NE 0.     MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno     WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.  ENDIF.*依字段目录产出参考目录CLEAR lt_alv_cat.LOOP AT lt_table ASSIGNING FIELD-SYMBOL(<fs_table>).   ls_alv_cat-fieldname = ls_alv_cat-ref_field = <fs_table>-fieldname.   ls_alv_cat-ref_table = p_tab_n.   APPEND ls_alv_cat TO lt_alv_cat.   CLEAR: <fs_table>,ls_alv_cat.ENDLOOP.UNASSIGN <fs_table>.CALL METHOD cl_alv_table_create=>create_dynamic_table  EXPORTING    it_fieldcatalog           = lt_alv_cat  IMPORTING    ep_table                  = d_ref.  IF sy-subrc NE 0.     MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno     WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.  ENDIF.ASSIGN d_ref->* TO <dyn_table>.ASSIGN d_ref TO <dyn_tmp_struc>.ENDFORM.*&---------------------------------------------------------------------**&      Form  excel_upload*&---------------------------------------------------------------------**& Begin Date  : 2021/02/02*& Author      : Kevin Yu*& Description : 将 Excel data 从本地端传至宣告的 Table 中*----------------------------------------------------------------------**& Version     :*----------------------------------------------------------------------*FORM excel_upload TABLES table. DATA: lt_data_in_file TYPE TABLE OF          zalsmex_tabline,       ls_data_in_file TYPE                   zalsmex_tabline,       lv_count        TYPE i,       lv_count_2      TYPE i.DATA truxs_t_text_data(4096) TYPE c OCCURS 0. "不影响回传资料,仅因 FUNCTION 需求而设"DATA: gt_data         TYPE alsmex_tabline OCCURS 0 WITH HEADER LINE."不影响回传资料,仅因 FUNCTION 需求而设CLEAR table.CALL FUNCTION 'TEXT_CONVERT_XLS_TO_SAP'    EXPORTING*     I_FIELD_SEPERATOR          =      i_line_header              =  'X'      i_tab_raw_data             =  truxs_t_text_data      i_filename                 =  p_infile    TABLES      i_tab_converted_data       =  table   EXCEPTIONS     conversion_failed          = 1     OTHERS                     = 2            .  IF sy-subrc NE 0.     MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno     WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.  ENDIF.ENDFORM.*&---------------------------------------------------------------------**&      Form  display_data*&---------------------------------------------------------------------**& Begin Date  : 2021/02/02*& Author      : Kevin Yu*& Description : 呈现 Excel 上传至 table 中的资料 --OO ALV*----------------------------------------------------------------------**& Version     :*----------------------------------------------------------------------*FORM display_data USING table."如要再 PAI 做 OO ALV 跳转时,要REFRESH ALV 物件及 GUI" refresh_table_display & SAPGUI_SET_FUNCTIONCODE   IF grid1 IS INITIAL.           g_custom_container       = NEW cl_gui_custom_container( g_container ).           grid1                    = NEW cl_gui_alv_grid( g_custom_container  ).           CALL METHOD grid1->set_table_for_first_display               EXPORTING i_structure_name = p_tab_n                         is_print         = gs_print                         is_layout        = gs_layout               CHANGING  it_outtab        = table.           CALL METHOD grid1->refresh_table_display              EXCEPTIONS                 finished = 1                 OTHERS   = 2.    ELSE.        CALL METHOD grid1->set_table_for_first_display               EXPORTING i_structure_name = p_tab_n                         is_print         = gs_print                         is_layout        = gs_layout               CHANGING  it_outtab        = table.        CALL METHOD grid1->refresh_table_display              EXCEPTIONS                 finished = 1                 OTHERS   = 2.    ENDIF.        IF sy-subrc <> 0.* Implement suitable error handling here    ENDIF.CALL FUNCTION 'SAPGUI_SET_FUNCTIONCODE' " 人为触发 PBO           EXPORTING             functioncode           = 'REFRESH'           EXCEPTIONS             function_not_supported = 1             OTHERS                 = 2.ENDFORM.*&---------------------------------------------------------------------**& Module PBO OUTPUT*&---------------------------------------------------------------------**&*&---------------------------------------------------------------------*MODULE pbo OUTPUT.  SET PF-STATUS 'STANDARD'.  IF gv_noinput EQ cl_abap_typedescr=>true.   ASSIGN '1200' TO <gv_screen_no>.  ELSE.   ASSIGN '1100' TO <gv_screen_no>.  ENDIF.  CHECK grid1 IS NOT INITIAL.*  IF  gv_modify EQ 'X'.*    PERFORM alv_modify.*  ENDIF.  CALL METHOD grid1->refresh_table_display  EXCEPTIONS  finished = 1  OTHERS   = 2.ENDMODULE.*&---------------------------------------------------------------------**&      Module  PAI  INPUT*&---------------------------------------------------------------------**       text*----------------------------------------------------------------------*MODULE pai INPUT."CALL METHOD cl_gui_cfw=>dispatch. "人为触发 PAI  CLEAR gv_noinput. CASE ok_code.    WHEN  'ENDE' OR 'ECAN'.      PERFORM exit_program.    WHEN  'EXE' OR 'ONLI' .     PERFORM authorization_check.    WHEN  'GET'.      PERFORM exit_program.    WHEN  'E'.      IF gs_layout-edit EQ cl_abap_typedescr=>true. "'X'.      gs_layout-edit = cl_abap_typedescr=>false.      PERFORM authorization_check.      ENDIF.    WHEN  'CHANGE_MODE'.      CHECK grid1 IS NOT INITIAL.      gv_noinput = cl_abap_typedescr=>true. "X"      gv_modify  = cl_abap_typedescr=>true. "X"      PERFORM alv_modify TABLES <dyn_table>.    WHEN  'SPOS'.    PERFORM alv_modify TABLES <dyn_table>.    WHEN 'ENTRY_DATA'.    PERFORM data_entry.  ENDCASE.  CLEAR ok_code.ENDMODULE.FORM exit_program.* CALL METHOD G_CUSTOM_CONTAINER->FREE.*  CALL METHOD CL_GUI_CFW=>FLUSH.  LEAVE TO SCREEN 0.ENDFORM.*&---------------------------------------------------------------------**&      Form  alv_modify*&---------------------------------------------------------------------**& Begin Date  : 2021/02/03*& Author      : Kevin Yu*& Description :*----------------------------------------------------------------------**& Version     :*----------------------------------------------------------------------*FORM    alv_modify  TABLES pt_list .IF gs_layout-edit = cl_abap_typedescr=>true.   gs_layout-edit = cl_abap_typedescr=>false.ELSE.   gs_layout-edit = cl_abap_typedescr=>true.ENDIF. CALL METHOD grid1->register_edit_event    EXPORTING i_event_id = cl_gui_alv_grid=>mc_evt_enter. CALL METHOD grid1->set_table_for_first_display               EXPORTING i_structure_name = p_tab_n                         is_print         = gs_print                         is_layout        = gs_layout               CHANGING  it_outtab        = <dyn_table>. CALL METHOD grid1->refresh_table_display              EXCEPTIONS                 finished = 1                 OTHERS   = 2.ENDFORM.

首先为了使Selection Screen 与 ALV 呈现在相同介面
必须要先自製自己的 Screen,并将ALV 包入物件中,并使用Custom Control 来呈现 ALV 物件
http://img2.58codes.com/2024/20135008RcKnUo20Ze.png
http://img2.58codes.com/2024/20135008OyMxKsz5Jn.png

而为了使介面呈现Selection Screen 的部分,在PBO 及 PAI 皆要调用其作为subscreen,如此便可让两者同时
存在于同一画面中
http://img2.58codes.com/2024/201350089i4v15mM1F.png

而接着便是创建 ALV 相关物件
可参照程式TOP做宣告类型 ,运用宣告类型如下

g_container           TYPE scrfname VALUE 'ALV_P'grid1                 TYPE REF TO cl_gui_alv_gridgs_print              TYPE lvc_s_prntgs_layout             TYPE lvc_s_layog_custom_container    TYPE REF TO cl_gui_custom_container

物件创建如下

           g_custom_container       = NEW cl_gui_custom_container( g_container ).           grid1                    = NEW cl_gui_alv_grid( g_custom_container  ).

準备好相关参数后接着调用 Method->set_table_for_first_display
便可在所设计的custom control 位置中呈现 alv

 CALL METHOD grid1->set_table_for_first_display               EXPORTING i_structure_name = p_tab_n                         is_print         = gs_print                         is_layout        = gs_layout               CHANGING  it_outtab        = <dyn_table>.

而其中要注意的便是 alv 刷新问题
通常在刷新 alv 会调用Method->refresh_table_display

 CALL METHOD grid1->refresh_table_display              EXCEPTIONS                 finished = 1                 OTHERS   = 2.

然而因此範例并非再 PBO 处理,故要自行触发PBO 刷新 GUI 介面

CALL FUNCTION 'SAPGUI_SET_FUNCTIONCODE' " 人为触发 PBO           EXPORTING             functioncode           = 'REFRESH'           EXCEPTIONS             function_not_supported = 1             OTHERS                 = 2.

至于其他细节就提供给各位看官自行研究啦~


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章