ABAP标准化报表设计与实现

@SAP ABAP标准化报表设计与实现

背景

设计的初衷:

1、减少重复性工作,提升效率。

把报表常用的过程抽象到全局类 ZCL_REPORT_ 中,将其作为模板类在本地继承后快速开发报表。

2、记录报表运行信息,统计报表使用和运行情况。

通过 save_log 方法记录报表运行数据,后续可用于统计分析报表的使用情况。

3、可按需扩展自定义功能。

在模板类中按需扩展新功能(比如问卷调查等),进行统一管控。

应用展示

一个简单的例子

REPORT zdemo.

CLASS cl_report DEFINITION INHERITING FROM zcl_report_ CREATE PUBLIC FINAL.
  PUBLIC SECTION.
    METHODS constructor.

  PROTECTED SECTION.

    METHODS process REDEFINITION. "主要处理过程,在这里取数、处理数据

    METHODS set_salv REDEFINITION. "在salv显示前进行设置

    METHODS added_function REDEFINITION. "自定义按钮 (已set handler)

    METHODS double_click REDEFINITION. "双击(已set handler)

  PRIVATE SECTION.
    DATA t_list TYPE TABLE OF spfli.

    METHODS get_flight_plan.

ENDCLASS.

START-OF-SELECTION.

  CAST zif_report_( NEW cl_report( ) )->execute( ).

CLASS cl_report IMPLEMENTATION.
  METHOD constructor. "构造方法

    super->constructor( ).

    config-list_header = `This is a sense of things to come`.

    r_display_table = REF #( t_list ). "设置要显示的内表

  ENDMETHOD.

  METHOD process. "主要处理过程

    " ...

    get_flight_plan( ). "具体处理内容

    " ...

  ENDMETHOD.

  METHOD get_flight_plan.

    SELECT * INTO TABLE t_list FROM spfli.

  ENDMETHOD.

  METHOD set_salv. "在salv显示前进行设置

    TRY.

        r_salv_column = r_salv_columns_table->get_column( `CARRID` ).
        r_salv_column->set_short_text( `hellokitty` ).
        r_salv_column->set_medium_text( `hellokitty` ).
        r_salv_column->set_long_text( `hellokitty` ).
        r_salv_column->set_zero( space ).

      CATCH cx_root.

    ENDTRY.

  ENDMETHOD.

  METHOD added_function. "自定义按钮

  ENDMETHOD.


  METHOD double_click. "双击

    MESSAGE 'double click event triggered' TYPE `S`.

  ENDMETHOD.

ENDCLASS.

执行结果:
在这里插入图片描述

运行日志:
在这里插入图片描述
ZCL_REPORT_中集成了日志记录、SALV显示等功能,

大部分情况下,只要把上面的代码拷到新程序,在process方法

里写一下取数和处理数据的逻辑就完成一个报表开发了,非常方便。

如果遇见了复杂场景,salv显示满足不了需求,那就把display方法重载了再按需实现。

只需两分钟,一个Report Log Statistic报表就出炉了~如下:

在这里插入图片描述
有了运行数据就可以掌握报表的运行情况:

哪些报表运行时间长,需要重点关注、优化性能,

交付给用户的报表有没有运行,频率怎么样,

哪个报表(功能)在什么时间被哪个用户执行过,

这些信息都可以轻松查到。

实现过程

接口和类

事物代码 SE24 创建接口 ZIF_REPORT_
在这里插入图片描述

创建抽象类 ZCL_REPORT_ 在这里插入图片描述

类的方法
在这里插入图片描述

构造方法:

* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_REPORT_->CONSTRUCTOR
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD constructor.

    "标准化报表缺省设置

    config-save_log = enabled. "保存运行日志,默认:启用

    config-default_salv = enabled. "使用自带的SALV显示,默认:启用

    config-list_display = disabled. "LIST显示,默认:不启用

    config-report_name = `SAPLKKBL`. "默认的gui status程序名

    config-gui_status = `STANDARD_FULLSCREEN`. "默认的gui status名

  ENDMETHOD.

主执行方法:

* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_REPORT_->ZIF_REPORT_~EXECUTE
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD zif_report_~execute.

    TRY.

        check( ).      "检查参数有效性和权限等

        save_log( 1 ). "开始记录运行信息

        process( ).    "主要处理过程

        save_log( 2 ). "结束记录运行信息

        display( ).    "数据显示

      CATCH zcx_rp_msg INTO DATA(lcx_rp_msg). "捕获上述方法中抛出的异常

        MESSAGE lcx_rp_msg->get_text( ) TYPE `S` DISPLAY LIKE `E`.

    ENDTRY.

  ENDMETHOD.

日志记录方法:

* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_REPORT_->SAVE_LOG
* +-------------------------------------------------------------------------------------------------+
* | [--->] STEP                           TYPE        I
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD save_log.

    DATA lv_stamp TYPE timestampl.

    CHECK config-save_log EQ enabled.

    CASE step.

      WHEN 1.

        TRY.
            s_log-lognm = cl_system_uuid=>create_uuid_c32_static( ).
          CATCH cx_uuid_error.
            RETURN.
        ENDTRY.

        IF s_log-lognm IS INITIAL.
          RETURN.
        ENDIF.

        s_log-cprog = sy-cprog.
        s_log-tcode = sy-tcode.
        s_log-uname = sy-uname.
        s_log-batch = sy-batch.
        s_log-slset = sy-slset.
        s_log-host  = sy-host.

        SELECT SINGLE unam
          INTO s_log-unam
          FROM reposrc
         WHERE progname EQ sy-cprog.

        CALL FUNCTION 'GUI_GET_DESKTOP_INFO'
          EXPORTING
            type   = 5
          CHANGING
            return = s_log-os_name.

        CALL FUNCTION 'TH_USER_INFO'
          IMPORTING
            terminal = s_log-terminal
            addrstr  = s_log-ip.

        GET TIME STAMP FIELD lv_stamp.

        CONVERT TIME STAMP lv_stamp TIME ZONE 'UTC+8' INTO DATE s_log-process_begda
                                                           TIME s_log-process_begti.
        s_log-process_endda  = s_log-process_begda.
        s_log-process_endti  = s_log-process_begti.
        s_log-process_stamp1 = s_log-process_stamp2 = frac( lv_stamp ).
        MODIFY zreport_log FROM s_log.

      WHEN 2.

        IF s_log-lognm IS INITIAL.
          RETURN.
        ENDIF.

        GET TIME STAMP FIELD lv_stamp.

        CONVERT TIME STAMP lv_stamp TIME ZONE 'UTC+8' INTO DATE s_log-process_endda
                                                           TIME s_log-process_endti.

        s_log-process_stamp2 = frac( lv_stamp ).

        DATA(s1) = s_log-process_begti+0(2) * 3600
           + s_log-process_begti+2(2) * 60
           + s_log-process_begti+4(2) * 1.

        DATA(s2) = s_log-process_endti+0(2) * 3600
           + s_log-process_endti+2(2) * 60
           + s_log-process_endti+4(2) * 1
           + ( s_log-process_endda - s_log-process_begda ) * 86400.

        s_log-process_duration = s2 - s1 + s_log-process_stamp2 - s_log-process_stamp1.

        UPDATE zreport_log
           SET process_endda    = s_log-process_endda
               process_endti    = s_log-process_endti
               process_stamp2   = s_log-process_stamp2
               process_begda    = s_log-process_begda
               process_begti    = s_log-process_begti
               process_stamp1   = s_log-process_stamp1
               process_duration = s_log-process_duration
         WHERE lognm EQ s_log-lognm.

    ENDCASE.

  ENDMETHOD.

日志表 ZREPORT_LOG 字段设计
在这里插入图片描述

  * <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Protected Method ZCL_REPORT_->DISPLAY
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD display.

    FIELD-SYMBOLS <lt_list> TYPE table.

    CHECK config-default_salv EQ enabled.

    ASSIGN r_display_table->* TO <lt_list>.

    CHECK <lt_list> IS ASSIGNED.

    TRY.
        cl_salv_table=>factory(
          EXPORTING
            list_display = config-list_display
          IMPORTING
            r_salv_table = r_salv_table
          CHANGING
            t_table      = <lt_list> ).
      CATCH cx_salv_msg INTO DATA(lcx_salv_msg).
        MESSAGE lcx_salv_msg->get_text( ) TYPE `E`.
    ENDTRY.

    "获取 SALV 属性
    r_salv_layout = r_salv_table->get_layout( ).

    r_salv_selections = r_salv_table->get_selections( ).

    r_salv_functions_list = r_salv_table->get_functions( ).

    r_salv_columns_table = r_salv_table->get_columns( ).

    r_salv_sorts = r_salv_table->get_sorts( ).

    r_salv_aggregations = r_salv_table->get_aggregations( ).

    r_salv_filters = r_salv_table->get_filters( ).

    r_salv_events_table = r_salv_table->get_event( ).

    r_salv_events ?= r_salv_events_table.

    r_salv_display_settings = r_salv_table->get_display_settings( ).

    "设置 SALV 属性

    s_salv_layout_key-report = sy-cprog.

    s_stbl-row = `X`.
    s_stbl-col = `X`.

    r_salv_table->set_screen_status( report   = config-report_name
                                     pfstatus = config-gui_status ).

    r_salv_layout->set_default( `X` ).

    r_salv_layout->set_save_restriction( 3 ).

    r_salv_layout->set_key( s_salv_layout_key ).

    r_salv_columns_table->set_optimize( `X` ).

    r_salv_functions_list->set_all( `X` ).

    r_salv_selections->set_selection_mode( 4 ).

    CREATE OBJECT r_salv_form_layout_grid.

    IF config-alv_title IS INITIAL.
      config-alv_title = |条目数 { lines( <lt_list> ) }|.
    ENDIF.

    r_salv_form_layout_grid->create_label(
      EXPORTING
        row    = 1
        column = 1
        text   = config-alv_title ).

    r_salv_table->set_top_of_list( r_salv_form_layout_grid ).

    IF config-list_header IS NOT INITIAL.
      r_salv_display_settings->set_list_header( config-list_header ).
    ENDIF.

    SET HANDLER added_function FOR r_salv_events.
    SET HANDLER double_click FOR r_salv_events_table.
    SET HANDLER link_click FOR r_salv_events_table.

    set_salv( ).  "显示前的自定义设置,覆盖上面的默认设置

    r_salv_table->display( ).

  ENDMETHOD.

总结

简单的小设计,把一些小点子集中实现,没有什么难点。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值