ABAP 执行程序并获取展示数据FUNCTION

支持输入程序/TCODE按筛选变式条件或条件表执行程序,获取程序输出内容

输出可以是GRID ALV或LIST  ALV或WRITE输出

思路扩展:可以结合发送邮件程序/接口推送给用户,形成报表监控机制,主动推送用户异常数据

代码逻辑:

1.检查输入

2.设置ALV设置memory

3.按变式或筛选条件执行程序

4.获取程序执行结果

代码如下,拿走即用,无自定义内容

由于用到BDC,需要在函数组TOP部分增加代码:

INCLUDE bdcrecxy.
FUNCTION zbc_get_alv_data.
*"----------------------------------------------------------------------
*"*"區域介面:
*"  IMPORTING
*"     VALUE(I_TCODE_REPORT) TYPE  PROGRAM_ID
*"     VALUE(I_SELVAR) TYPE  RALDB_VARI OPTIONAL
*"  EXPORTING
*"     REFERENCE(E_ALVDATA) TYPE  DATA
*"     REFERENCE(E_MSGTY) TYPE  MSGTY
*"     REFERENCE(E_MSGTX) TYPE  MSGTX
*"  TABLES
*"      IT_RSPAR STRUCTURE  RSPARAMS OPTIONAL
*"----------------------------------------------------------------------
  DATA:lv_report  LIKE  rsvar-report,
       lv_variant LIKE  rsvar-variant,
       lt_valutab LIKE  TABLE OF rsparams.

  DATA:   messtab LIKE bdcmsgcoll OCCURS 0 WITH HEADER LINE.
  DATA:ctumode LIKE ctu_params-dismode VALUE 'N',
       cupdate LIKE ctu_params-updmode VALUE 'S'.

  DATA:
    lr_alv_data	           TYPE REF TO data,
    lr_alv_data_line       TYPE REF TO data,
    lr_alv_data_descr	     TYPE REF TO cl_abap_datadescr,
    lr_alv_data_line_descr TYPE REF TO cl_abap_datadescr.

  DATA:lt_component_data TYPE if_salv_bs_t_data=>t_type_component.
  DATA:lt_component_data_line TYPE if_salv_bs_t_data=>t_type_component.

  FIELD-SYMBOLS:<lt_data> TYPE STANDARD TABLE.
  FIELD-SYMBOLS:<lt_data_line> TYPE STANDARD TABLE.

  CLEAR:p_tcode,p_report,p_selvar.

**********************************************************************
***                          輸入檢查
**********************************************************************

  SELECT SINGLE
    tcode,
    pgmna
    FROM tstc
    WHERE tcode = @i_tcode_report
     OR pgmna = @i_tcode_report
    INTO ( @p_tcode,@p_report ).
  IF sy-subrc <> 0.
    "程序没有TCODE的情况
    SELECT SINGLE
      name
      FROM trdir
      WHERE name = @i_tcode_report
      INTO @p_report.
    IF sy-subrc <> 0.
      e_msgtx = 'TCODE/程序:' && i_tcode_report && '不存在!'.
      e_msgty = 'E'.EXIT.
    ENDIF.
  ELSE.
    IF it_rspar[] IS NOT INITIAL.
      CLEAR p_tcode."筛选条件表只能按程序执行,不能用TCODE执行
    ENDIF.
  ENDIF.

  IF i_selvar IS NOT INITIAL.
    p_selvar = i_selvar.

    SELECT SINGLE
    report,
    variant
    FROM varid
    WHERE report = @p_report
    AND   variant = @p_selvar
    INTO @DATA(ls_varid).
    IF sy-subrc <> 0.
      e_msgtx = '筛选变式' && p_selvar && '和TCODE/程序的不匹配,請檢查!'.
      e_msgty = 'E'.EXIT.
    ENDIF.
  ENDIF.

**********************************************************************
***                          获取程序数据
**********************************************************************
  "设置memory获取ALV展示数据
  CALL METHOD cl_salv_bs_runtime_info=>set
    EXPORTING
      display  = abap_false "不显示ALV
      metadata = abap_true
      data     = abap_true. "将数据传入memory

  IF i_tcode_report = p_tcode .
    CLEAR bdcdata[].
    "获取筛选界面变式内容
    IF p_selvar IS NOT INITIAL.
      PERFORM frm_bdc_selvar.
    ENDIF.

    PERFORM frm_bdc_ation.

***按TCODE执行程序
    REFRESH messtab.
    TRY.
        CALL TRANSACTION p_tcode WITH AUTHORITY-CHECK USING bdcdata
              MODE   ctumode
              UPDATE cupdate
              MESSAGES INTO messtab.
      CATCH cx_sy_authorization_error INTO DATA(lx_auth_check).
*     Authorization missing for user when executing transaction
        DATA(l_auth_check_text) = lx_auth_check->get_text( ).
        e_msgtx = l_auth_check_text.
        e_msgty = 'E'.EXIT.
    ENDTRY.
  ELSEIF p_report IS NOT INITIAL.
    IF it_rspar[] IS INITIAL.
      "获取筛选界面变式内容
      IF p_selvar IS NOT INITIAL.
        CALL FUNCTION 'RS_VARIANT_CONTENTS'
          EXPORTING
            report               = p_report
            variant              = p_selvar
            move_or_write        = 'M'
          TABLES
            valutab              = lt_valutab
          EXCEPTIONS
            variant_non_existent = 1
            variant_obsolete     = 2
            OTHERS               = 3.
        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.
    ELSE.
      lt_valutab[] = it_rspar[].
    ENDIF.

***按程序名执行程序
    SUBMIT (p_report)
    WITH SELECTION-TABLE lt_valutab "多选
    EXPORTING LIST TO MEMORY
    AND RETURN.
  ENDIF.


***通过memory获取ALV显示数据
  "獲取內存數據 "由於get_data_ref方法獲取r_data_line時不傳輸r_data參數,會導致DUMP"
*      CALL METHOD cl_salv_bs_runtime_info=>get_data_ref
*        IMPORTING
*          r_data            = lr_alv_data
*          r_data_line       = lr_alv_data_line
*          r_data_descr      = lr_alv_data_descr
*          r_data_line_descr = lr_alv_data_line_descr.
  TRY.
      "獲取DATA結構構造動態內表
      IMPORT t_component TO lt_component_data FROM MEMORY ID cl_salv_bs_runtime_info=>c_memid_data_def.
      IF sy-subrc EQ 0 AND lines( lt_component_data[] ) > 2.
        cl_salv_bs_ddic=>create_data_from_components(
          EXPORTING
            t_component = lt_component_data
          IMPORTING
            r_data      = lr_alv_data
            r_datadescr = lr_alv_data_descr ).

        IF lr_alv_data IS NOT INITIAL.
          ASSIGN lr_alv_data->* TO <lt_data>.
        ENDIF.
      ENDIF.

      "獲取DATA_LINE結構構造動態內表
      IMPORT t_component TO lt_component_data_line FROM MEMORY ID cl_salv_bs_runtime_info=>c_memid_data_line_def.
      IF sy-subrc EQ 0 AND lines( lt_component_data_line[] ) > 2.
        cl_salv_bs_ddic=>create_data_from_components(
          EXPORTING
            t_component = lt_component_data_line
          IMPORTING
            r_data      = lr_alv_data_line
            r_datadescr = lr_alv_data_line_descr ).

        IF lr_alv_data_line IS NOT INITIAL.
          ASSIGN lr_alv_data_line->* TO <lt_data_line>.
        ENDIF.
      ENDIF.

      "先按ALV_LIST获取,未获取到则按ALV_GRID
      IF <lt_data_line> IS ASSIGNED.
        IMPORT t_data_line TO <lt_data_line> FROM MEMORY ID cl_salv_bs_runtime_info=>c_memid_data_line.
        IF sy-subrc = 0.
          e_alvdata = lr_alv_data_line.
        ENDIF.
      ENDIF.

      IF e_alvdata IS INITIAL.
        IF <lt_data> IS ASSIGNED.
          IMPORT t_data TO <lt_data> FROM MEMORY ID cl_salv_bs_runtime_info=>c_memid_data.
          IF sy-subrc = 0.
            e_alvdata = lr_alv_data.
          ENDIF.
        ENDIF.
      ENDIF.

***通过WRITE输出的程序通过MEMORY获取展示数据
      IF e_alvdata IS INITIAL.
        DATA: lt_list TYPE TABLE OF abaplist.
        CALL FUNCTION 'LIST_FROM_MEMORY'
          TABLES
            listobject = lt_list
          EXCEPTIONS
            not_found  = 1
            OTHERS     = 2.
        IF sy-subrc = 0.
          DATA: lt_ascii TYPE TABLE OF soli.
          CALL FUNCTION 'LIST_TO_ASCI'
            TABLES
              listasci           = lt_ascii
              listobject         = lt_list
            EXCEPTIONS
              empty_list         = 1
              list_index_invalid = 2
              OTHERS             = 3.
          IF sy-subrc = 0 AND lt_ascii[] IS NOT INITIAL.
            "创建动态表结构
            CREATE DATA e_alvdata TYPE TABLE OF soli.
            e_alvdata->* = lt_ascii[].
*            创建动态内表
*            ASSIGN e_alvdata->* TO <dyn_table>.
*
*            <dyn_table> = lt_ascii[].
          ENDIF.
        ENDIF.
      ENDIF.


      IF e_alvdata IS INITIAL.
        e_msgtx = '无符合条件的数据!'.
        e_msgty = 'E'.EXIT.
      ELSE.
        e_msgtx = '数据获取成功!'.
        e_msgty = 'S'.
      ENDIF.

    CATCH cx_salv_bs_sc_runtime_info.
      e_msgtx = '数据获取失败,该程序不支持此函数使用!'.
      e_msgty = 'E'.EXIT.
  ENDTRY.

*  TRY.
*      CALL METHOD cl_salv_bs_runtime_info=>get_metadata
*        RECEIVING
*          value = ls_alv_metadata.
*    CATCH cx_salv_bs_sc_runtime_info.
*  ENDTRY.

* Should not be CLEAR_ALL if not call by others
* Clear runtime info
  CALL METHOD cl_salv_bs_runtime_info=>clear_all.

ENDFUNCTION.
*&---------------------------------------------------------------------*
*& Form frm_bdc_selvar
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_bdc_selvar .
  PERFORM bdc_dynpro      USING p_report '1000'.
  PERFORM bdc_field       USING 'BDC_OKCODE' '/EGET'.

  PERFORM bdc_dynpro      USING 'SAPMSSY0' '0120'.
  PERFORM bdc_field       USING 'BDC_OKCODE' '=%SC'.

  PERFORM bdc_dynpro      USING 'SAPLSYSF' '0800'.
  PERFORM bdc_field       USING 'BDC_OKCODE' '=SCAN'.
  PERFORM bdc_field       USING 'RSYSF-STRING' p_selvar.
  PERFORM bdc_field       USING 'SCAN_STRING-START' 'X'.

  PERFORM bdc_dynpro      USING 'SAPMSSY0' '0120'.
  PERFORM bdc_field       USING 'BDC_CURSOR' '03/07'.
  PERFORM bdc_field       USING 'BDC_OKCODE' '=POSI'.

  PERFORM bdc_dynpro      USING 'SAPMSSY0' '0120'.
  PERFORM bdc_field       USING 'BDC_OKCODE' '=PICK'.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_BDC_ATION
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_bdc_ation .
  PERFORM bdc_dynpro      USING p_report '1000'.
  PERFORM bdc_field       USING 'BDC_OKCODE' '=ONLI'.
ENDFORM.

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐