动手开发一个有用的 ABAP ALV 工具 - 查看指定用户的 ABAP 传输请求,模拟 SE10 事物码

我们知道 ABAP 系统里有一个有用的工具,事物码 SE10,输入用户名称,可以查看该用户在本系统上创建的传输请求(Transport Request)列表:

动手开发一个有用的 ABAP ALV 工具 - 查看指定用户的 ABAP 传输请求,模拟 SE10 事物码_第1张图片

点击 Display 按钮,能看到用户名 WANGJER 下面的所有传输请求:

动手开发一个有用的 ABAP ALV 工具 - 查看指定用户的 ABAP 传输请求,模拟 SE10 事物码_第2张图片

每个传输请求可以展开,查看里面具体包含的 ABAP 对象。很多 ABAP 对象,比如上图蓝色高亮的 ABAP 类方法,双击之后,可以用 ABAP 编辑器打开这些方法,查看其实现源代码。

本教程我们已经用了几个步骤的篇幅,介绍了 ABAP ALV 的开发步骤:

本文我们来使用以前所学习的知识,动手开发一个类似 SE10 的工具。这个工具也是笔者实际工作中开发的一个工具,这里分享给各位 ABAP 学习者。

这个工具允许用户输入指定的用户名,执行之后,在 ALV 列表里列出该用户在该系统创建的所有传输请求,并自动把传输请求里包含的 ABAP 对象(包括 ABAP 类,ABAP DDIC 对象等等)也显示出来,如下图所示:

动手开发一个有用的 ABAP ALV 工具 - 查看指定用户的 ABAP 传输请求,模拟 SE10 事物码_第3张图片

动手开发一个有用的 ABAP ALV 工具 - 查看指定用户的 ABAP 传输请求,模拟 SE10 事物码_第4张图片

单击上图的 ALV 行项目,同样能自动跳转到 ABAP 编辑器里,打开这些 ABAP 对象,效果如下图所示:

动手开发一个有用的 ABAP ALV 工具 - 查看指定用户的 ABAP 传输请求,模拟 SE10 事物码_第5张图片

下面我们介绍这个工具的详细设计思路,开发步骤和全部源代码。

这个工具的主干程序很精简,代码如下,包含 4 个 ABAP include 程序。每个 ABAP include 程序负责实现一项特定的业务逻辑。通过将业务逻辑拆分到不同的 ABAP include 程序,使我们工具实现的代码结构和逻辑更清晰,可读性更好。

主干程序和 4 个 ABAP include 程序的 smc,代表 Social Media Cockpit,这是笔者当时参与的 CRM 项目的缩写。

动手开发一个有用的 ABAP ALV 工具 - 查看指定用户的 ABAP 传输请求,模拟 SE10 事物码_第6张图片

zsmc_data

我们在 SE38 里创建的 ABAP 程序,默认类型都是可以运行的报表,即 executable program,如果要创建 include program,从下拉列表里选择对应的类型即可。

动手开发一个有用的 ABAP ALV 工具 - 查看指定用户的 ABAP 传输请求,模拟 SE10 事物码_第7张图片

这个 include 的任务是定义所有需要在这个工具里使用到的 ABAP 变量:

动手开发一个有用的 ABAP ALV 工具 - 查看指定用户的 ABAP 传输请求,模拟 SE10 事物码_第8张图片

ZSMC_TR

这个 include 的任务是从数据库表 e070 里读取出指定用户在当前 ABAP 系统里创建的所有传输请求的 id,存储到 ABAP 内表 lt_trlist 里。

动手开发一个有用的 ABAP ALV 工具 - 查看指定用户的 ABAP 传输请求,模拟 SE10 事物码_第9张图片

比如在笔者使用的 AG3 系统上,我总共创建了 595 个传输请求:

动手开发一个有用的 ABAP ALV 工具 - 查看指定用户的 ABAP 传输请求,模拟 SE10 事物码_第10张图片

e070 数据库表只维护了用户名和传输请求 id 之间的关系,如果我们想知道每个传输请求里包含了哪些 ABAP 开发对象,需要采取其他办法来查找。

ZSMC_PREPARE_DATA

这个 ABAP include 负责将 ZSMC_TR include 里编写的逻辑,即从 e070 数据库表里取出的 ABAP 传输请求 id 进行解析,取出每一个传输请求包含的 ABAP 对象。

解析操作通过 Function Module 完成,解析结果如下图所示:

动手开发一个有用的 ABAP ALV 工具 - 查看指定用户的 ABAP 传输请求,模拟 SE10 事物码_第11张图片

上图函数的 Tables 参数 et_e071,存储的就是传输请求里包含的不同类型的 ABAP 对象。这些 ABAP 对象的类型,通过字段 PGMIDOBJECT 进行区分。

  • R3TR.CLAS, 代表存储在传输请求里的是 ABAP 类名称
  • LIMU.METH, 代表存储在传输请求里的是 ABAP 类的方法实现

动手开发一个有用的 ABAP ALV 工具 - 查看指定用户的 ABAP 传输请求,模拟 SE10 事物码_第12张图片

ZSMC_ALV

负责 ABAP ALV 的数据显示和点击事件处理。

如图所示,我们使用 Function Module REUSE_ALV_GRID_DISPLAY 来输出 ALV 报表。

这个函数有一个输入参数 i_callback_user_command, 可以指定一个用户自定义的 subroutine,用于处理 ALV 的点击事件。

如下图所示,当我们单击 ALV 报表某些可以点击的列时,我们通过代码 123 行指定的 subroutine,ALV_USER_COMMAND 会自动被触发,在这个 subroutine 里我们调用自己编写的另一个 subroutine display_object,来实现自动打开对应的 ABAP 编辑器以查看的功能。

动手开发一个有用的 ABAP ALV 工具 - 查看指定用户的 ABAP 传输请求,模拟 SE10 事物码_第13张图片

比如我们单击下图红色的行项目 CL_ABAP_GIT_ISSUE_IMAGE_TOOL

动手开发一个有用的 ABAP ALV 工具 - 查看指定用户的 ABAP 传输请求,模拟 SE10 事物码_第14张图片

从调试器里的函数上下文调用栈能看出,我们编写的 subroutine ALV_USER_COMMAND 被调用,输入参数 ct_selfield 包含了被点击的行项目的索引 12,所以我们可以从 ALV 报表的数据源,lt_dev_object 内表里,通过 READ TABLE INDEX XXX 的 ABAP 语句将该行项目的明细读取出来:

动手开发一个有用的 ABAP ALV 工具 - 查看指定用户的 ABAP 传输请求,模拟 SE10 事物码_第15张图片

行项目 ABAP 对象的类型,通过输入参数 ct_selfield 的字段 fieldname 来区分。如果字段名称为 TRKORR, 说明这个行项目是一个传输请求,此时调用第 150 行的工具函数 TR_PRESENT_REQUEST 来显示这个传输请求。

否则,说明该行项目是一个普通的 ABAP 对象,此时调用能处理绝大多数 ABAP 对象显示功能的 RS_TOOL_ACCESS 来实现 ABAP 对象的显示操作。

动手开发一个有用的 ABAP ALV 工具 - 查看指定用户的 ABAP 传输请求,模拟 SE10 事物码_第16张图片

ALV 报表里具体哪些列支持单击事件处理呢?只需要将传入函数 REUSE_ALV_GRID_DISPLAY 的输入参数 it_fieldcat 里包含的每一列对应的 hotspot 字段设置为 X 即可。

如下图所示,代码的语义就是,我们期望 OBJ_NAMETRKORR 这两列,即对象名称和传输请求号能够支持单击操作。

动手开发一个有用的 ABAP ALV 工具 - 查看指定用户的 ABAP 传输请求,模拟 SE10 事物码_第17张图片

这两个支持单击操作的列如下图所示,用户很容易区分,因为其值下有一条下划线,显示成超链接的效果。

动手开发一个有用的 ABAP ALV 工具 - 查看指定用户的 ABAP 传输请求,模拟 SE10 事物码_第18张图片

本例完整的源代码如下:

主程序:

REPORT ZSMC_OBJECT_LIST.

PARAMETERS: user type usr02-bname DEFAULT sy-uname OBLIGATORY.
INCLUDE zsmc_data.
INCLUDE zsmc_tr.
INCLUDE zsmc_prepare_data.
INCLUDE zsmc_alv.

INITIALIZATION.
  PERFORM init.
START-OF-SELECTION.

  PERFORM fill_trlist.
  PERFORM fill_data.
  PERFORM alv_display.

ZSMC_DATA:

*&---------------------------------------------------------------------*
*&  Include           ZSMC_DATA
*&---------------------------------------------------------------------*

TYPES: begin of ty_dev_object,
            obj_name TYPE string,
            pgm_id TYPE char4,
            object TYPE char4,
            trkorr TYPE char20,
            as4user TYPE char12,
            as4date TYPE d,
            as4time TYPE t,
            as4text TYPE char60,
            package TYPE tadir-devclass,
            tech_name TYPE tadir-obj_name,
            color TYPE lvc_t_scol,
       END OF ty_dev_object.

TYPES: tt_dev_object TYPE STANDARD TABLE OF ty_dev_object WITH KEY obj_name pgm_id object trkorr.

DATA: lt_trkorr TYPE TABLE OF scwbtrkorr,
      ls_trkorr LIKE LINE OF lt_trkorr,
      lt_trlist TYPE string_table,
      lt_e070 TYPE STANDARD TABLE OF SCWB_E070,
      lt_e070t TYPE STANDARD TABLE OF SCWB_E07T,
      lt_e070c TYPE STANDARD TABLE OF SCWB_E070C,
      lt_e071  TYPE STANDARD TABLE OF SCWB_E071,
      lt_e071k TYPE STANDARD TABLE OF SCWB_E071K,
      lt_e070a TYPE STANDARD TABLE OF SCWB_E070A,
      lt_dev_object TYPE tt_dev_object,
      ls_dev_object TYPE ty_dev_object.

DATA: lv_col TYPE lvc_s_scol,
      lt_coltab TYPE lvc_t_scol,
      ls_color TYPE lvc_s_colo,
      lt_ic TYPE string_table.

FIELD-SYMBOLS:  LIKE LINE OF lt_e071,
                LIKE LINE OF lt_e070,
                LIKE LINE OF lt_e070t.

ZSMC_TR:

*&---------------------------------------------------------------------*
*&  Include           ZSMC_TR
*&---------------------------------------------------------------------*

FORM fill_trlist.
   PERFORM log USING 10 'Fetching Transport request from DB...'.
   PERFORM add_tr USING user.
ENDFORM.

FORM add_tr USING name TYPE char12.
   DATA: lt_e070 TYPE STANDARD TABLE OF e070.

   FIELD-SYMBOLS: TYPE e070.
   SELECT trkorr as4user INTO CORRESPONDING FIELDS OF TABLE lt_e070 FROM e070 WHERE as4user = name.

   LOOP AT lt_e070 ASSIGNING .
      APPEND -trkorr TO lt_trlist.
   ENDLOOP.
ENDFORM.

FORM log USING per TYPE i text TYPE string.
   CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
       EXPORTING
           percentage = per
           text = text.
ENDFORM.

ZSMC_PREPARE_DATA:

*&---------------------------------------------------------------------*
*&  Include           ZSMC_PREPARE_DATA
*&---------------------------------------------------------------------*

FORM fill_data.

DATA: lv_tr TYPE string.

LOOP AT lt_trlist INTO lv_tr.
      ls_trkorr-trkorr  = lv_tr.
      ls_trkorr-srcsyst = space.
      APPEND ls_trkorr TO lt_trkorr.
      ls_trkorr-srcsyst = lv_tr(3).
      APPEND ls_trkorr TO lt_trkorr.
ENDLOOP.

CALL FUNCTION 'SCWB_GET_COMPL_REQUESTS_REM_40'
      EXPORTING
        iv_merge_object_lists = ' '
      TABLES
        it_request_numbers    = lt_trkorr
        et_e070               = lt_e070
        et_e07t               = lt_e070t
        et_e070c              = lt_e070c
        et_e071               = lt_e071
        et_e070a              = lt_e070a
      EXCEPTIONS
        error_message         = 0.   "suppres

SORT lt_e070 BY trkorr.
SORT lt_e070t BY trkorr.
PERFORM log USING 50 'Analyzing object information from Transport request...'.
LOOP AT lt_e071 ASSIGNING  WHERE object <> 'CORR' AND object <> 'AVAS' AND object <> 'PDWS' AND object <> 'DLCS' AND object <> 'CDAT'
   AND object <> 'TDAT' AND object <> 'SMIM' AND object <> 'RELE' AND object <> 'MERG' AND object <> 'CLSD' AND object <> 'CPRO'
   AND object <> 'CPUB' AND object <> 'CPRI' AND object <> 'DOCU' AND object <> 'SICF' AND object <> 'MESS' AND object <> 'PIFA'
   AND object <> 'SHI6' AND object <> 'SHI3' AND object <> 'TABU' AND object <> 'VDAT'.
   ls_dev_object-trkorr = -trkorr.
   ls_dev_object-pgm_id = -pgmid.
   ls_dev_object-object = -object.
   ls_dev_object-obj_name = -obj_name.
   READ TABLE lt_e070t ASSIGNING  WITH KEY trkorr = -trkorr BINARY SEARCH.
   IF sy-subrc = 0.
      ls_dev_object-as4text = -as4text.
      IF -as4text CS 'Generated test transport'.
         CONTINUE.
      ENDIF.
   ENDIF.

   READ TABLE lt_e070 ASSIGNING  WITH KEY trkorr = -trkorr BINARY SEARCH.
   IF sy-subrc = 0.
      ls_dev_object-as4user = -as4user.
      ls_dev_object-as4date = -as4date.
      ls_dev_object-as4time = -as4time.
   ENDIF.
   READ TABLE lt_e070t ASSIGNING  WITH KEY trkorr = -trkorr BINARY SEARCH.
   IF sy-subrc = 0.
      ls_dev_object-as4text = -as4text.
   ENDIF.

   IF -object <> 'METH'.
       ls_dev_object-tech_name = -obj_name.
   ELSE.
       PERFORM get_tech_name CHANGING ls_dev_object.
   ENDIF.

   APPEND ls_dev_object TO lt_dev_object.
ENDLOOP.

SORT lt_dev_object BY obj_name.
DELETE ADJACENT DUPLICATES FROM lt_dev_object COMPARING obj_name as4user as4text.

ENDFORM.

FORM get_tech_name CHANGING ls_dev_object TYPE ty_dev_object.
   DATA: lt_temp TYPE string_table.
   SPLIT ls_dev_object-obj_name AT space INTO TABLE lt_temp.
   READ TABLE lt_temp INTO ls_dev_object-tech_name INDEX 1.
ENDFORM.

FORM init.
   APPEND 'CRM_IC_APPL_INBOX' TO lt_ic.
   APPEND 'CRM_IC_CMP_INBOX' TO lt_ic.
   APPEND 'CRM_IC_CMP_BTX' TO lt_ic.
   ls_color-col = '6'.
   ls_color-int = '0'.
   ls_color-inv = '0'.
   lv_col-fname = 'OBJECT'.
   lv_col-color = ls_color.
   APPEND lv_col TO lt_coltab.
   lv_col-fname = 'TRKORR'.
   APPEND lv_col TO lt_coltab.
   lv_col-fname = 'AS4USER'.
   APPEND lv_col TO lt_coltab.
   lv_col-fname = 'AS4DATE'.
   APPEND lv_col TO lt_coltab.
   lv_col-fname = 'AS4TIME'.
   APPEND lv_col TO lt_coltab.
   lv_col-fname = 'AS4TEXT'.
   APPEND lv_col TO lt_coltab.
ENDFORM.

ZSMC_ALV:

*&---------------------------------------------------------------------*
*&  Include           ZSMC_ALV
*&---------------------------------------------------------------------*

  DATA ls_layout   TYPE slis_layout_alv.
  DATA lt_sort     TYPE slis_t_sortinfo_alv.
  DATA gt_fieldcat TYPE SLIS_T_FIELDCAT_ALV.
  DATA lt_event    TYPE SLIS_T_EVENT.
  data ls_event    type slis_alv_event.

FORM alv_build_fieldcat CHANGING ct_fieldcat TYPE slis_t_fieldcat_alv.

  DATA lv_col_pos  TYPE i.
  DATA ls_fieldcat TYPE slis_fieldcat_alv.

  CLEAR ct_fieldcat.
  lv_col_pos = 1.

  CLEAR ls_fieldcat.
  ls_fieldcat-col_pos      = lv_col_pos.
  ls_fieldcat-fieldname    = 'OBJ_NAME'.
  ls_fieldcat-key          = 'X'.
  ls_fieldcat-hotspot      = 'X'.
  APPEND ls_fieldcat TO ct_fieldcat.
  ADD 1 TO lv_col_pos.

  CLEAR ls_fieldcat.
  ls_fieldcat-col_pos      = lv_col_pos.
  ls_fieldcat-fieldname    = 'OBJECT'.
  ls_fieldcat-rollname     = 'CHAR4'.
  ls_fieldcat-reptext_ddic = 'Object TYPE'.
  APPEND ls_fieldcat TO ct_fieldcat.
  ADD 1 TO lv_col_pos.

  CLEAR ls_fieldcat.
  ls_fieldcat-col_pos      = lv_col_pos.
  ls_fieldcat-fieldname    = 'TRKORR'.
  ls_fieldcat-rollname     = 'CHAR20'.
  ls_fieldcat-hotspot      = 'X'.
  ls_fieldcat-reptext_ddic = 'TR number'.
  APPEND ls_fieldcat TO ct_fieldcat.
  ADD 1 TO lv_col_pos.

  CLEAR ls_fieldcat.
  ls_fieldcat-col_pos      = lv_col_pos.
  ls_fieldcat-fieldname    = 'AS4USER'.
  ls_fieldcat-rollname     = 'CHAR12'.
  ls_fieldcat-reptext_ddic = 'Developer'.
  APPEND ls_fieldcat TO ct_fieldcat.
  ADD 1 TO lv_col_pos.

  CLEAR ls_fieldcat.
  ls_fieldcat-col_pos      = lv_col_pos.
  ls_fieldcat-reptext_ddic = 'Date'.
  ls_fieldcat-fieldname    = 'AS4DATE'.
  APPEND ls_fieldcat TO ct_fieldcat.
  ADD 1 TO lv_col_pos.

  CLEAR ls_fieldcat.
  ls_fieldcat-col_pos      = lv_col_pos.
  ls_fieldcat-fieldname    = 'AS4TIME'.
  ls_fieldcat-reptext_ddic = 'Time'.
  APPEND ls_fieldcat TO ct_fieldcat.
  ADD 1 TO lv_col_pos.

  CLEAR ls_fieldcat.
  ls_fieldcat-col_pos      = lv_col_pos.
  ls_fieldcat-fieldname    = 'AS4TEXT'.
  ls_fieldcat-reptext_ddic = 'Description'.
  APPEND ls_fieldcat TO ct_fieldcat.
  ADD 1 TO lv_col_pos.

ENDFORM.                    "alv_build_fieldcat

FORM alv_build_layout USING es_layout TYPE slis_layout_alv.

  es_layout-colwidth_optimize = 'X'.
  es_layout-zebra             = 'X'.
  es_layout-coltab_fieldname = 'COLOR'.

ENDFORM.                    "alv_build_layout

*&---------------------------------------------------------------------*
*&      Form  alv_build_sorting
*&---------------------------------------------------------------------*
FORM alv_build_sorting USING et_sort TYPE slis_t_sortinfo_alv.
  DATA ls_sort LIKE LINE OF et_sort.

  CLEAR ls_sort.
  ls_sort-fieldname = 'OBJ_NAME'.
  ls_sort-up = 'X'.
  APPEND ls_sort TO et_sort.

ENDFORM.

FORM html_top_of_page USING document TYPE REF TO cl_dd_document.

  DATA: text TYPE sdydo_text_element.
  text =  '用户传输请求查看小工具'.
  CALL METHOD document->add_text
    EXPORTING
      text      = text
      sap_style = 'HEADING'.

ENDFORM.                    "HTML_TOP_OF_PAGE
FORM alv_display.
  PERFORM alv_build_fieldcat CHANGING gt_fieldcat.
  PERFORM alv_build_layout   USING ls_layout.
  PERFORM alv_build_sorting  USING lt_sort.

  ls_event-name = 'DATA_CHANGED'.
  ls_event-form = 'DATA_CHANGED'.
  append ls_event to lt_event.

  PERFORM log USING 80 'Determining Package information...'.

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program       = sy-repid
      i_callback_pf_status_set = 'ALV_SET_STATUS'
      i_callback_html_top_of_page = 'HTML_TOP_OF_PAGE'
      i_callback_user_command  = 'ALV_USER_COMMAND'
      is_layout                = ls_layout
      it_fieldcat              = gt_fieldcat
      it_sort                  = lt_sort
      it_events                = lt_event
      i_grid_title             = 'Transport Request Object List'
    TABLES
      t_outtab                 = lt_dev_object
    EXCEPTIONS
      program_error            = 1
      OTHERS                   = 2.
  ASSERT sy-subrc = 0.
ENDFORM.

FORM ALV_USER_COMMAND USING iv_ucomm     LIKE sy-ucomm
                             ct_selfield  TYPE slis_selfield."#EC CALLED .
   PERFORM display_object USING ct_selfield.
ENDFORM.

FORM display_object USING ct_selfield TYPE slis_selfield.
   FIELD-SYMBOLS:  TYPE ty_dev_object.

   READ TABLE lt_dev_object ASSIGNING  INDEX ct_selfield-tabindex.
   CHECK sy-subrc = 0.

   IF ct_selfield-fieldname = 'TRKORR'.
     SET PARAMETER ID 'KOR' FIELD -trkorr.
     CALL FUNCTION 'TR_PRESENT_REQUEST'
        EXPORTING
          iv_trkorr    = -trkorr
          iv_highlight = 'X'.
   ELSE.

     CALL FUNCTION 'RS_TOOL_ACCESS'
       EXPORTING
         operation   = 'SHOW'
         object_name = -obj_name
         object_type = -object
       EXCEPTIONS
         OTHERS      = 1.
   ENDIF.

ENDFORM.

FORM ALV_SET_STATUS USING it_exclude TYPE table.
   SET PF-STATUS 'ZALV'.
ENDFORM.

你可能感兴趣的:(动手开发一个有用的 ABAP ALV 工具 - 查看指定用户的 ABAP 传输请求,模拟 SE10 事物码)