Wednesday 13 September 2017

Simplify your life: Searching text strings in SAP code - enhancements, SAPSCRIPT, SMARTFORMS or ADOBE forms

Introduction


A recurrent issue is to search all kinds of ABAP code for text strings. SAP standard program AFX_CODE_SCANNER does a great job, but lacks the search in code of enhancements, Sapscript, smartforms and Adobe forms and interfaces.

I will post the code for ZAFX_CODE_SCANNER, an adjusted copy, which does have those options, and can search the other areas. Please use at your advantage.

But first let me describe how I get to the code for enhancements/sapscript/smartforms and Adobe.

Enhancements


AFX_CODE_SCANNER retrieves information from the TADIR-table, all code-object have entries in this table.

The addition to search in enhancement code has been:

select * from tadir into table l_tab_tadir
      where pgmid    = 'R3TR' and
            object   = 'ENHO'.

    select single enhinclude from enhincinx
      into l_incl where enhname = l_str_tadir-obj_name.

    l_rep_name = l_incl.

read report l_rep_name into l_tab_source.
    if sy-subrc = 0.
      perform scan_prog using    u_devc
                                 l_rep_name
                                 u_cnt_line
                        changing l_tab_source.

So objects type ENHO are read from TADIR, and include-report code is read from table ENHINCINX, and ZAFX_CODE_SCANNER continues similar as for other reports with a “read report” and a “perform_scan”

SAPSCRIPT


Sapscript code lines can be retrieved with function “READ_FORM”, It cannot be done with a “read report”

In order to show the window in the output, so the code can be located easily at the loop on the lines every time a “/W” is found the window-name is put into a variable. This window-element is put into the output table in a new field called “form”,

select * from tadir into table l_tab_tadir
      where pgmid    = 'R3TR' and
            object   = 'FORM'.

    data l_form type itcta-tdform.

    l_form = l_str_tadir-obj_name.

    call function 'READ_FORM'
      exporting
*       CLIENT     = SY-MANDT
        form       = l_form
*       LANGUAGE   = SY-LANGU
*       OLANGUAGE  = ' '
*       OSTATUS    = ' '
*       STATUS     = ' '
*       THROUGHCLIENT          = ' '
*       READ_ONLY_HEADER       = ' '
*       THROUGHLANGUAGE        = ' '
* IMPORTING
*       FORM_HEADER            =
*       FOUND      =
*       HEADER     =
*       OLANGUAGE  =
      tables
        form_lines = lt_data "this contains all code lines
*       PAGES      =
*       PAGE_WINDOWS           =
*       PARAGRAPHS =
*       STRINGS    =
*       TABS       =
*       WINDOWS    =
      . 

* Search source for selection criteria
    loop at lt_data into l_str_source.
      g_line_number = sy-tabix.
      clear l_flg_write.
      if l_str_source-line cs '/W'.
        l_element = l_str_source-line+2(10).
      endif.
      if l_str_source-line cs p_strg1 and
         ( p_strg2 is initial or l_str_source-line cs p_strg2 ).
        if ( p_excl1 is initial or
             not l_str_source-line cs p_excl1 ) and
           ( p_excl2 is initial or
             not l_str_source-line cs p_excl2 ) and
           ( p_excl3 is initial or
             not l_str_source-line cs p_excl3 ) and
           ( p_excomm is initial or
             l_str_source-line(1) <> '*' ).
          l_flg_write = con_true.
          l_cnt_line  = 0.
        endif.
      endif.

      if l_flg_write = con_true or l_cnt_line < u_cnt_line.
        l_cnt_line  = l_cnt_line + 1.
        l_flg_found = con_true.

        l_str_lines-linno = g_line_number.
        l_str_lines-line  = l_str_source-line.

        l_str_lines-progname = l_form.
        l_str_lines-form = l_element.

        append l_str_lines to g_tab_lines.
      endif.

    endloop.

The search-part is adjusted code from the “perform_scan” module.

l_str_lines_form is an added element.

The program will show occurences of the search text, but will not have the possibility to jump to the code. You will have to open the SE71 transaction and open the form element for the mentioned program to edit the code.

SMARTFORMS


The code for smartforms is in a generated function module, which can be retrieved with FM “SSF_FUNCTION_MODULE_NAME”

You have to make sure the code from the function module is searched.

select * from tadir into table l_tab_tadir
      where pgmid    = 'R3TR' and
            object   = 'SSFO'.

  data l_form type  tdsfname.
  data l_formname type  string.
  data l_fm_name type  rs38l_fnam.

    clear l_fm_name.
    l_form = l_str_tadir-obj_name.
    l_formname = l_str_tadir-obj_name.
    call function 'SSF_FUNCTION_MODULE_NAME'
      exporting
        formname           = l_form
      importing
        fm_name            = l_fm_name
      exceptions
        no_form            = 1
        no_function_module = 2
        others             = 3.

*   Get function pool objects
*    write: / l_str_tadir-obj_name.
    l_str_e071-pgmid    = 'R3TR'.
    l_str_e071-object   = 'FUGR'.
    l_str_e071-obj_name = l_fm_name.
    refresh l_tab_e071.
    call function 'STOR_RESOLVE_FUGR'
      exporting
        is_e071 = l_str_e071
      tables
        tt_e071 = l_tab_e071
      exceptions
        others  = 0.

*   Read basis program sources and search for specified strings
    loop at l_tab_e071 into l_str_e071 where object = 'REPO' .
      l_rep_name = l_str_e071-obj_name.
      refresh l_tab_source.
      read report l_rep_name into l_tab_source.
      if sy-subrc = 0.

        perform scan_prog2 using    u_devc
                                   l_rep_name
                                   l_formname
                                   u_cnt_line
                          changing l_tab_source.

After you have retrieved the function module name, the code is similar to that of searches in function module groups.

A copy of perform scan_prog is made to add l_formname to the output for identification.

Adobe forms


Just like smartforms Adobe forms have a generated function module. The function module to be used to retrieve the name is different: FP_FUNCTION_MODULE_NAME.

select * from tadir into table l_tab_tadir
      where pgmid    = 'R3TR' and
            object   = 'SFPF'.

  data l_form type  fpname.
  data l_formname type  string.
  data l_fm_name type  funcname.

   l_form = l_str_tadir-obj_name.
    l_formname = l_str_tadir-obj_name.
    try.
        call function 'FP_FUNCTION_MODULE_NAME'
          exporting
            i_name     = l_form
          importing
            e_funcname = l_fm_name.
      catch cx_fp_api_repository.
        continue.
      catch     cx_fp_api_usage.
        continue.
      catch     cx_fp_api_internal.
        continue.
    endtry.

*   Get function pool objects
*    write: / l_str_tadir-obj_name.
    l_str_e071-pgmid    = 'R3TR'.
    l_str_e071-object   = 'FUGR'.
    l_str_e071-obj_name = l_fm_name.
    refresh l_tab_e071.
    call function 'STOR_RESOLVE_FUGR'
      exporting
        is_e071 = l_str_e071
      tables
        tt_e071 = l_tab_e071
      exceptions
        others  = 0.

*   Read basis program sources and search for specified strings
    loop at l_tab_e071 into l_str_e071 where object = 'REPO' .
      l_rep_name = l_str_e071-obj_name.
      refresh l_tab_source.
      read report l_rep_name into l_tab_source.
      if sy-subrc = 0.

        perform scan_prog2 using    u_devc
                                   l_rep_name
                                   l_formname
                                   u_cnt_line
                          changing l_tab_source.

Otherwise this behaves similar to the search in smartform-code.

All of the code


Feel free to use the next (large and complete) piece of code to test the search in the above mentioned areas. I have not payed much attention to clean coding. Feel free to structure the code at your convenience.

*&---------------------------------------------------------------------*
*& Report  ZAFX_CODE_SCANNER                                           *
*&                                                                     *
*&---------------------------------------------------------------------*
*&                                                                     *
*&                                                                     *
*&---------------------------------------------------------------------*

REPORT  zafx_code_scanner.

INCLUDE afx_global_data_public.

TYPE-POOLS: slis.

TYPES: BEGIN OF t_str_lines,
         devclass LIKE tadir-devclass,
         progname LIKE rs38m-programm,
         form     LIKE rs38m-programm,
         linno    LIKE rslgaxdata-line,
         line     LIKE abapsource-line,
       END   OF t_str_lines.

DATA: BEGIN OF g_tab_lines OCCURS 0,
        devclass LIKE tadir-devclass,
        progname LIKE rs38m-programm,
        form     LIKE rs38m-programm,
        linno    LIKE rslgaxdata-line,
        line     LIKE abapsource-line,
      END   OF g_tab_lines.

* Global data
TABLES:    tadir.                                           "#EC NEEDED
CONSTANTS: c_devc_tmp    TYPE devclass VALUE '$TMP'.
DATA:      g_line_object TYPE sobj_name,
           g_line_number TYPE sytabix.
TYPES: BEGIN OF t_abapsource_long,  "CB
         line TYPE char255,
       END OF   t_abapsource_long.
TYPES: t_tab_long_lines TYPE STANDARD TABLE OF t_abapsource_long.  "CB

*-----------------------------------------------------------------------
*-----------------------------------------------------------------------
SELECTION-SCREEN: BEGIN OF BLOCK a WITH FRAME TITLE text-001.
SELECT-OPTIONS:     s_devc FOR  tadir-devclass OBLIGATORY MEMORY ID dvc.
SELECT-OPTIONS:     s_rest FOR  tadir-obj_name. "MEMORY ID dvc.
SELECTION-SCREEN:   SKIP.
PARAMETERS:         p_strg1(80) OBLIGATORY,
                    p_strg2(80).
SELECTION-SCREEN: END   OF BLOCK a.

SELECTION-SCREEN: BEGIN OF BLOCK b WITH FRAME TITLE text-002.
PARAMETERS:         p_excl1(80),
                    p_excl2(80),
                    p_excl3(80).
SELECTION-SCREEN:   SKIP.
PARAMETERS:         p_lrng(2)    TYPE n OBLIGATORY DEFAULT '01'.
SELECTION-SCREEN:   SKIP.
PARAMETERS:         p_excomm AS CHECKBOX DEFAULT con_false,
                    p_nohits AS CHECKBOX DEFAULT con_false,
                    p_edit   AS CHECKBOX DEFAULT con_false.
SELECTION-SCREEN: END   OF BLOCK b.

SELECTION-SCREEN: BEGIN OF BLOCK c WITH FRAME TITLE text-003.
PARAMETERS:         p_prog  AS CHECKBOX DEFAULT con_true,
                    p_fugr  AS CHECKBOX DEFAULT con_true,
                    p_cinc  AS CHECKBOX DEFAULT con_true,
                    p_enh   AS CHECKBOX DEFAULT con_true,
                    p_scrip AS CHECKBOX DEFAULT con_true,
                    p_smart AS CHECKBOX DEFAULT con_true,
                    p_adobe AS CHECKBOX DEFAULT con_true.

SELECTION-SCREEN: END   OF BLOCK c.

*-----------------------------------------------------------------------
*-----------------------------------------------------------------------
START-OF-SELECTION.
  PERFORM process_devc.

*-----------------------------------------------------------------------
*-----------------------------------------------------------------------
AT LINE-SELECTION.
  PERFORM navigate_to_object USING g_line_object g_line_number p_edit.

*---------------------------------------------------------------------*
*       FORM process_devc                                             *
*---------------------------------------------------------------------*
FORM process_devc.
  DATA: l_tab_tadir       TYPE TABLE OF tadir,
        l_str_tadir       TYPE tadir,
        l_cnt             TYPE i,
        l_cnt_str(10)     TYPE c,
        l_tabix           TYPE i,
        l_flg_process_tmp TYPE xfeld,
        l_answer          TYPE c,
        l_popuptext(200)  TYPE c,
        l_devclass        TYPE devclass.

* Initialization
  REFRESH g_tab_lines.

* Get all packages matching with selection criteria
  REFRESH l_tab_tadir.
  SELECT * FROM tadir INTO TABLE l_tab_tadir
    WHERE pgmid    = 'R3TR' AND
          object   = 'DEVC' AND
          devclass IN s_devc.                         "#EC CI_SGLSELECT

* Ignore invalid TADIR entries.
  DELETE l_tab_tadir WHERE obj_name IS INITIAL.

  DESCRIBE TABLE l_tab_tadir LINES l_cnt.

* Check if local package $TMP in selection criteria
  CLEAR l_flg_process_tmp.
  IF c_devc_tmp IN s_devc.
    l_flg_process_tmp = con_true.
    l_cnt = l_cnt + 1.
  ENDIF.

* Check count of selected packages
  IF l_cnt > 10 AND sy-batch <> con_true.
    l_cnt_str = l_cnt.
    CONDENSE l_cnt_str.

    CONCATENATE 'Es wurden folgende Anzahl von Paketen selektiert:'(004)
                 l_cnt_str 'Scan-Vorgang trotzdem starten?'(005)
                INTO l_popuptext SEPARATED BY space.

    CALL FUNCTION 'POPUP_TO_CONFIRM'
      EXPORTING
        titlebar              = 'Sicherheitsabfrage'(006)
        text_question         = l_popuptext
        default_button        = '2'
        display_cancel_button = con_false
      IMPORTING
        answer                = l_answer.
    IF l_answer <> '1'.
      EXIT.
    ENDIF.
  ENDIF.

* Process packages
  l_tabix = 0.
  LOOP AT l_tab_tadir INTO l_str_tadir.
    l_tabix = l_tabix + 1.
    l_devclass = l_str_tadir-obj_name.
    PERFORM scan_devc USING l_devclass l_tabix l_cnt p_lrng.
  ENDLOOP.

* Process local package $TMP
  IF l_flg_process_tmp = con_true.
    l_tabix = l_tabix + 1.
    PERFORM scan_devc USING c_devc_tmp l_tabix l_cnt p_lrng.
  ENDIF.

* Display scan result data
  PERFORM scan_result_display.

ENDFORM.                    "process_devc

*&---------------------------------------------------------------------*
*&      Form  scan_result_display
*&---------------------------------------------------------------------*
FORM scan_result_display.
  DATA: l_str_layout     TYPE slis_layout_alv,
        l_tab_all_events TYPE slis_t_event,
        l_tab_events     TYPE slis_t_event,
        l_str_event      TYPE slis_alv_event,
        l_repid          TYPE syrepid,
        l_tab_sort       TYPE slis_t_sortinfo_alv,
        l_str_sort       TYPE slis_sortinfo_alv,
        l_tab_fieldcat   TYPE slis_t_fieldcat_alv,
        l_str_fieldcat   TYPE slis_fieldcat_alv.

* Initialzation
  CLEAR:   l_str_layout,
           l_str_event,
           l_str_sort,
           l_str_fieldcat.
  REFRESH: l_tab_all_events,
           l_tab_events,
           l_tab_sort,
           l_tab_fieldcat.
  l_repid = sy-repid.

* Initialize Layout for activity log
  l_str_layout-detail_popup         = con_true.
  l_str_layout-detail_initial_lines = con_true.
  l_str_layout-expand_all           = con_true.
  l_str_layout-colwidth_optimize    = con_true.
  l_str_layout-zebra                = con_true.

* Get possible events
  CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
    EXPORTING
      i_list_type = 0
    IMPORTING
      et_events   = l_tab_all_events.

* User-command for activity log
  READ TABLE l_tab_all_events WITH KEY name = slis_ev_user_command
             INTO l_str_event.
  IF sy-subrc = 0.
    l_str_event-form = 'ALV_USER_COMMAND'.
    APPEND l_str_event TO l_tab_events.
  ENDIF.

  l_str_sort-spos = '01'.
  l_str_sort-fieldname = 'DEVCLASS'.
  l_str_sort-up = con_true.

  APPEND l_str_sort TO l_tab_sort.

  l_str_sort-spos = '02'.
  l_str_sort-fieldname = 'PROGNAME'.
  l_str_sort-up = con_true.
  APPEND l_str_sort TO l_tab_sort.

  CALL FUNCTION 'REUSE_ALV_FIELDCATALOG_MERGE'
    EXPORTING
      i_program_name         = l_repid
      i_internal_tabname     = 'G_TAB_LINES'
*     I_STRUCTURE_NAME       =
*     I_CLIENT_NEVER_DISPLAY = con_true
      i_inclname             = l_repid
      i_bypassing_buffer     = con_true
*     I_BUFFER_ACTIVE        =
    CHANGING
      ct_fieldcat            = l_tab_fieldcat
    EXCEPTIONS
      inconsistent_interface = 1
      program_error          = 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.

  READ TABLE l_tab_fieldcat WITH KEY fieldname = 'LINNO'
             INTO l_str_fieldcat.
  IF sy-subrc = 0.
    l_str_fieldcat-hotspot = con_true.
    l_str_fieldcat-just = 'R'.
    MODIFY l_tab_fieldcat FROM l_str_fieldcat INDEX sy-tabix.
  ENDIF.

  READ TABLE l_tab_fieldcat WITH KEY fieldname = 'LINE'
             INTO l_str_fieldcat.
  IF sy-subrc = 0.
    l_str_fieldcat-emphasize = 'C500'.
*'Cxyz'; x=Farbcode entspr. Farbliste
*        y=intensified
*        z=inverse
    l_str_fieldcat-lzero = con_true.
    MODIFY l_tab_fieldcat FROM l_str_fieldcat INDEX sy-tabix.
  ENDIF.

***  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
  CALL FUNCTION 'REUSE_ALV_LIST_DISPLAY'
    EXPORTING
*     I_INTERFACE_CHECK  = con_false
*     I_BYPASSING_BUFFER = con_false
*     I_BUFFER_ACTIVE    = ' '
      i_callback_program = l_repid
*     I_CALLBACK_PF_STATUS_SET          = con_false
*     I_CALLBACK_USER_COMMAND           = con_false
*     I_CALLBACK_TOP_OF_PAGE            = con_false
*     I_CALLBACK_HTML_TOP_OF_PAGE       = con_false
*     I_CALLBACK_HTML_END_OF_LIST       = con_false
*     i_structure_name   = con_false
*     I_BACKGROUND_ID    = con_false
*     I_GRID_TITLE       =
*     I_GRID_SETTINGS    =
      is_layout          = l_str_layout
      it_fieldcat        = l_tab_fieldcat
*     IT_EXCLUDING       =
*     IT_SPECIAL_GROUPS  =
      it_sort            = l_tab_sort
*     IT_FILTER          =
*     IS_SEL_HIDE        =
*     I_DEFAULT          = con_true
      i_save             = 'A'
*     IS_VARIANT         =
      it_events          = l_tab_events
*     IT_EVENT_EXIT      =
*     IS_PRINT           =
*     IS_REPREP_ID       =
*     I_SCREEN_START_COLUMN             = 0
*     I_SCREEN_START_LINE               = 0
*     I_SCREEN_END_COLUMN               = 0
*     I_SCREEN_END_LINE  = 0
*     IT_ALV_GRAPHICS    =
*     IT_HYPERLINK       =
*     IT_ADD_FIELDCAT    =
*     IT_EXCEPT_QINFO    =
*     I_HTML_HEIGHT_TOP  =
*     I_HTML_HEIGHT_END  =
* IMPORTING
*     E_EXIT_CAUSED_BY_CALLER           =
*     ES_EXIT_CAUSED_BY_USER            =
    TABLES
      t_outtab           = g_tab_lines
    EXCEPTIONS
      program_error      = 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.                    " scan_result_display

*---------------------------------------------------------------------*
*       FORM scan_devc                                                *
*---------------------------------------------------------------------*
FORM scan_devc USING u_devc         TYPE devclass
                     u_index        TYPE i
                     u_count        TYPE i
                     u_cnt_line     TYPE n.

* Scan sources of current package
  IF p_prog = con_true.
    PERFORM scan_devc_prog
      USING u_devc u_index u_count u_cnt_line.
  ENDIF.
  IF p_fugr = con_true.
    PERFORM scan_devc_fugr
      USING u_devc u_index u_count u_cnt_line.
  ENDIF.
  IF p_cinc = con_true.
    PERFORM scan_devc_class
      USING u_devc u_index u_count u_cnt_line.
  ENDIF.

  IF p_enh = con_true.
    PERFORM scan_devc_enh
      USING u_devc u_index u_count u_cnt_line.
  ENDIF.

  IF p_scrip = con_true.
    PERFORM scan_devc_scrip
      USING u_devc u_index u_count u_cnt_line.
  ENDIF.

  IF p_smart = con_true.
    PERFORM scan_devc_smart
      USING u_devc u_index u_count u_cnt_line.
  ENDIF.

  IF p_adobe = con_true.
    PERFORM scan_devc_adobe
      USING u_devc u_index u_count u_cnt_line.
  ENDIF.

ENDFORM.                    "scan_devc

*&---------------------------------------------------------------------*
*&      Form  scan_devc_prog
*&---------------------------------------------------------------------*
FORM scan_devc_prog USING u_devc     TYPE devclass
                          u_index    TYPE i
                          u_count    TYPE i
                          u_cnt_line TYPE n.
  DATA: l_tab_tadir     TYPE TABLE OF tadir,
        l_str_tadir     TYPE tadir,
        l_cnt           TYPE i,
        l_cnt_str(10)   TYPE c,
        l_idx_devc(10)  TYPE c,
        l_cnt_devc(10)  TYPE c,
        l_aux_devc(20)  TYPE c,
        l_percentage    TYPE p,
        l_tabix_str(10) TYPE c,
        l_rep_name      TYPE sobj_name,
        l_tab_source    TYPE t_tab_long_lines,    "CB
        l_text          TYPE itex132.

* Initialization
  l_idx_devc = u_index.
  l_cnt_devc = u_count.
  CONCATENATE l_idx_devc '/' l_cnt_devc INTO l_aux_devc.
  CONDENSE l_aux_devc.

* Get programs of current package
  REFRESH l_tab_tadir.
  IF u_devc <> c_devc_tmp.
    SELECT * FROM tadir INTO TABLE l_tab_tadir
      WHERE pgmid    = 'R3TR' AND
            object   = 'PROG' AND
            devclass = u_devc AND
            obj_name IN s_rest.                       "#EC CI_SGLSELECT

  ELSE.
    SELECT * FROM tadir INTO TABLE l_tab_tadir
      WHERE pgmid    = 'R3TR' AND
            object   = 'PROG' AND
            devclass = u_devc AND
            author   = sy-uname AND
            obj_name IN s_rest.                       "#EC CI_SGLSELECT
  ENDIF.

* Ignore invalid TADIR entries.
  DELETE l_tab_tadir WHERE obj_name IS INITIAL.

* Write count of programs into list
  DESCRIBE TABLE l_tab_tadir LINES l_cnt.
  IF l_cnt = 0.
    EXIT.
  ENDIF.

* Process all program sources
  l_cnt_str = l_cnt.
  CONDENSE l_cnt_str.
  LOOP AT l_tab_tadir INTO l_str_tadir.
    l_tabix_str = sy-tabix.
    CONDENSE l_tabix_str.

*   Display progress indicator
    l_percentage = 100 * ( sy-tabix / l_cnt ).
    CONCATENATE 'Scanne Paket'(008) u_devc l_aux_devc
                '(' 'Report'(009) l_tabix_str 'von'(010) l_cnt_str ')'
                INTO l_text SEPARATED BY space.
    CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
      EXPORTING
        percentage = l_percentage
        text       = l_text.

*   Read program source and search for specified strings
*    write: / l_str_tadir-obj_name.
    l_rep_name = l_str_tadir-obj_name.
    REFRESH l_tab_source.
    READ REPORT l_rep_name INTO l_tab_source.
    IF sy-subrc = 0.
      PERFORM scan_prog USING    u_devc
                                 l_rep_name
                                 u_cnt_line
                        CHANGING l_tab_source.     "CB
    ENDIF.

  ENDLOOP.

ENDFORM.                    " scan_devc_prog

*&---------------------------------------------------------------------*
*&      Form  scan_devc_fugr
*&---------------------------------------------------------------------*
FORM scan_devc_fugr USING u_devc     TYPE devclass
                          u_index    TYPE i
                          u_count    TYPE i
                          u_cnt_line TYPE n.
  DATA: l_tab_tadir     TYPE TABLE OF tadir,
        l_str_tadir     TYPE tadir,
        l_tab_e071      TYPE TABLE OF e071,
        l_str_e071      TYPE e071,
        l_str_tfdir     TYPE tfdir,
        l_cnt           TYPE i,
        l_cnt_str(10)   TYPE c,
        l_idx_devc(10)  TYPE c,
        l_cnt_devc(10)  TYPE c,
        l_aux_devc(20)  TYPE c,
        l_percentage    TYPE p,
        l_tabix_str(10) TYPE c,
        l_rep_name      TYPE sobj_name,
        l_tab_source    TYPE TABLE OF t_abapsource_long,       "CB
        l_text          TYPE itex132.

* Initialization
  l_idx_devc = u_index.
  l_cnt_devc = u_count.
  CONCATENATE l_idx_devc '/' l_cnt_devc INTO l_aux_devc.
  CONDENSE l_aux_devc.

* Get function pools of current package
  REFRESH l_tab_tadir.
  IF u_devc <> c_devc_tmp.
    SELECT * FROM tadir INTO TABLE l_tab_tadir
      WHERE pgmid    = 'R3TR' AND
            object   = 'FUGR' AND
            devclass = u_devc AND
            obj_name IN s_rest.                       "#EC CI_SGLSELECT
  ELSE.
    SELECT * FROM tadir INTO TABLE l_tab_tadir
      WHERE pgmid    = 'R3TR' AND
            object   = 'FUGR' AND
            devclass = u_devc AND
            author   = sy-uname AND
            obj_name IN s_rest.                       "#EC CI_SGLSELECT
  ENDIF.

* Ignore invalid TADIR entries.
  DELETE l_tab_tadir WHERE obj_name IS INITIAL.

* Write count of function pools into list
  DESCRIBE TABLE l_tab_tadir LINES l_cnt.
  IF l_cnt = 0.
    EXIT.
  ENDIF.

* Process all function pools
  l_cnt_str = l_cnt.
  CONDENSE l_cnt_str.
  LOOP AT l_tab_tadir INTO l_str_tadir.
    l_tabix_str = sy-tabix.
    CONDENSE l_tabix_str.

*   Display progress indicator
    l_percentage = 100 * ( sy-tabix / l_cnt ).
    CONCATENATE 'Scanne Paket'(008) u_devc l_aux_devc
                '(' 'FuGr'(011) l_tabix_str 'von'(010) l_cnt_str ')'
                INTO l_text SEPARATED BY space.
    CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
      EXPORTING
        percentage = l_percentage
        text       = l_text.

*   Get function pool objects
*    write: / l_str_tadir-obj_name.
    l_str_e071-pgmid    = l_str_tadir-pgmid.
    l_str_e071-object   = l_str_tadir-object.
    l_str_e071-obj_name = l_str_tadir-obj_name.
    REFRESH l_tab_e071.
    CALL FUNCTION 'STOR_RESOLVE_FUGR'
      EXPORTING
        is_e071 = l_str_e071
      TABLES
        tt_e071 = l_tab_e071
      EXCEPTIONS
        OTHERS  = 0.

*   Read basis program sources and search for specified strings
    LOOP AT l_tab_e071 INTO l_str_e071 WHERE object = 'REPO' .
      l_rep_name = l_str_e071-obj_name.
      REFRESH l_tab_source.
      READ REPORT l_rep_name INTO l_tab_source.
      IF sy-subrc = 0.
        PERFORM scan_prog USING    u_devc
                                   l_rep_name
                                   u_cnt_line
                          CHANGING l_tab_source.       "CB
      ENDIF.
    ENDLOOP .

* (A) Keine generierten Dialoge?!? Das sollte man evtl. optional
*     anbieten (Zeitpunkt-Routinen!)
*   Read function module sources and search for specified strings
    LOOP AT l_tab_e071 INTO l_str_e071 WHERE object = 'FUNC' .
      IF l_str_e071-obj_name(4) = 'VIEW'. "Keine gen. Dialoge
        CONTINUE.
      ENDIF.
      SELECT SINGLE * FROM tfdir INTO l_str_tfdir
        WHERE funcname = l_str_e071-obj_name.         "#EC CI_SGLSELECT
      IF sy-subrc = 0.
        CONCATENATE l_str_tfdir-pname 'U' l_str_tfdir-include
                    INTO l_rep_name.
        REPLACE 'SAPL' WITH 'L' INTO l_rep_name.
        REFRESH l_tab_source.
        READ REPORT l_rep_name INTO l_tab_source.
        IF sy-subrc = 0.
          PERFORM scan_prog USING    u_devc
                                     l_rep_name
                                     u_cnt_line
                            CHANGING l_tab_source.     "CB
        ENDIF.
      ENDIF.
    ENDLOOP.
  ENDLOOP .

ENDFORM.                    " scan_devc_fugr

*&---------------------------------------------------------------------*
*&      Form  scan_devc_prog
*&---------------------------------------------------------------------*
FORM scan_devc_enh USING u_devc     TYPE devclass
                          u_index    TYPE i
                          u_count    TYPE i
                          u_cnt_line TYPE n.
  DATA: l_tab_tadir     TYPE TABLE OF tadir,
        l_str_tadir     TYPE tadir,
        l_cnt           TYPE i,
        l_cnt_str(10)   TYPE c,
        l_idx_devc(10)  TYPE c,
        l_cnt_devc(10)  TYPE c,
        l_aux_devc(20)  TYPE c,
        l_percentage    TYPE p,
        l_tabix_str(10) TYPE c,
        l_incl          TYPE sobj_name,
        l_rep_name      TYPE sobj_name,
        l_tab_source    TYPE t_tab_long_lines,    "CB
        l_text          TYPE itex132.

* Initialization
  l_idx_devc = u_index.
  l_cnt_devc = u_count.
  CONCATENATE l_idx_devc '/' l_cnt_devc INTO l_aux_devc.
  CONDENSE l_aux_devc.

* Get programs of current package
  REFRESH l_tab_tadir.
  IF u_devc <> c_devc_tmp.
    SELECT * FROM tadir INTO TABLE l_tab_tadir
      WHERE pgmid    = 'R3TR' AND
            object   = 'ENHO' AND
            devclass = u_devc AND
            obj_name IN s_rest.                       "#EC CI_SGLSELECT

  ELSE.
    SELECT * FROM tadir INTO TABLE l_tab_tadir
      WHERE pgmid    = 'R3TR' AND
            object   = 'ENHO' AND
            devclass = u_devc AND
            author   = sy-uname AND
            obj_name IN s_rest.                       "#EC CI_SGLSELECT
  ENDIF.

* Ignore invalid TADIR entries.
  DELETE l_tab_tadir WHERE obj_name IS INITIAL.

* Write count of programs into list
  DESCRIBE TABLE l_tab_tadir LINES l_cnt.
  IF l_cnt = 0.
    EXIT.
  ENDIF.

* Process all program sources
  l_cnt_str = l_cnt.
  CONDENSE l_cnt_str.
  LOOP AT l_tab_tadir INTO l_str_tadir.
    l_tabix_str = sy-tabix.
    CONDENSE l_tabix_str.

*   Display progress indicator
    l_percentage = 100 * ( sy-tabix / l_cnt ).
    CONCATENATE 'Scanne Paket'(008) u_devc l_aux_devc
                '(' 'Report'(009) l_tabix_str 'von'(010) l_cnt_str ')'
                INTO l_text SEPARATED BY space.
    CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
      EXPORTING
        percentage = l_percentage
        text       = l_text.

*   Read program source and search for specified strings
*    write: / l_str_tadir-obj_name.

    SELECT SINGLE enhinclude FROM enhincinx
      INTO l_incl WHERE enhname = l_str_tadir-obj_name.

    IF sy-subrc <> 0.
      CONTINUE.
    ENDIF.

    l_rep_name = l_incl.
    REFRESH l_tab_source.
    READ REPORT l_rep_name INTO l_tab_source.
    IF sy-subrc = 0.
      PERFORM scan_prog USING    u_devc
                                 l_rep_name
                                 u_cnt_line
                        CHANGING l_tab_source.     "CB
    ENDIF.

  ENDLOOP.

ENDFORM.                    " scan_devc_enh

*&--------------------------------------------------------------------*
*&      Form  scan_devc_class
*&--------------------------------------------------------------------*
*       text
*---------------------------------------------------------------------*
*      -->U_DEVC     text
*      -->U_INDEX    text
*      -->U_COUNT    text
*      -->U_CNT_LINE text
*---------------------------------------------------------------------*
FORM scan_devc_class USING u_devc     TYPE devclass
                           u_index    TYPE i
                           u_count    TYPE i
                           u_cnt_line TYPE n.
  DATA: l_tab_tadir     TYPE TABLE OF tadir,
        l_str_tadir     TYPE tadir,
        l_str_e071      TYPE e071,
        l_cnt           TYPE i,
        l_cnt_str(10)   TYPE c,
        l_idx_devc(10)  TYPE c,
        l_cnt_devc(10)  TYPE c,
        l_aux_devc(20)  TYPE c,
        l_percentage    TYPE p,
        l_tabix_str(10) TYPE c,
        l_rep_name      TYPE sobj_name,
        l_tab_source    TYPE TABLE OF t_abapsource_long,
        l_text          TYPE itex132,
        l_tab_trdir     TYPE STANDARD TABLE OF trdir,
        l_str_trdir     LIKE LINE OF l_tab_trdir,
        l_tab_selopt    TYPE STANDARD TABLE OF rsdsselopt,
        l_str_selopt    LIKE LINE OF l_tab_selopt.

* Initialization
  l_idx_devc = u_index.
  l_cnt_devc = u_count.
  CONCATENATE l_idx_devc '/' l_cnt_devc INTO l_aux_devc.
  CONDENSE l_aux_devc.

* Get classes of current package
  REFRESH l_tab_tadir.
  IF u_devc <> c_devc_tmp.
    SELECT * FROM tadir INTO TABLE l_tab_tadir
      WHERE pgmid    = 'R3TR' AND
            object   = 'CLAS' AND
            devclass = u_devc AND
            obj_name IN s_rest.                       "#EC CI_SGLSELECT
  ELSE.
    SELECT * FROM tadir INTO TABLE l_tab_tadir
      WHERE pgmid    = 'R3TR' AND
            object   = 'CLAS' AND
            devclass = u_devc AND
            author   = sy-uname AND
            obj_name IN s_rest.                       "#EC CI_SGLSELECT
  ENDIF.

* Ignore invalid TADIR entries.
  DELETE l_tab_tadir WHERE obj_name IS INITIAL.

* Write count of function pools into list
  DESCRIBE TABLE l_tab_tadir LINES l_cnt.
  IF l_cnt = 0.
    EXIT.
  ENDIF.

* Process all function pools
  l_cnt_str = l_cnt.
  CONDENSE l_cnt_str.
  LOOP AT l_tab_tadir INTO l_str_tadir.
    l_tabix_str = sy-tabix.
    CONDENSE l_tabix_str.

*   Display progress indicator
    l_percentage = 100 * ( sy-tabix / l_cnt ).
    CONCATENATE 'Scanne Paket'(008) u_devc l_aux_devc
                '(' 'Klasse'(012) l_tabix_str 'von'(010) l_cnt_str ')'
                INTO l_text SEPARATED BY space.
    CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
      EXPORTING
        percentage = l_percentage
        text       = l_text.

* get includes for current class
    REFRESH l_tab_selopt.
    l_str_selopt-sign = 'I'.
    l_str_selopt-option = 'CP'.
    CONCATENATE l_str_tadir-obj_name '*' INTO
     l_str_selopt-low.
    APPEND l_str_selopt TO l_tab_selopt.

    SELECT * FROM trdir INTO TABLE l_tab_trdir
              WHERE name IN l_tab_selopt.             "#EC CI_SGLSELECT


    LOOP AT l_tab_trdir INTO l_str_trdir.
      l_rep_name = l_str_e071-obj_name.
      REFRESH l_tab_source.
      l_rep_name = l_str_trdir-name.
      READ REPORT l_rep_name INTO l_tab_source.

      IF sy-subrc = 0.
        PERFORM scan_prog USING    u_devc
                                   l_rep_name
                                   u_cnt_line
                          CHANGING l_tab_source.     "CB
      ELSE.
        FORMAT COLOR COL_NEGATIVE.
        WRITE: / 'Report'(009), l_rep_name, 'nicht gefunden!'(013).
      ENDIF.
    ENDLOOP.

  ENDLOOP .

ENDFORM.                    " scan_devc_class

*&---------------------------------------------------------------------*
*&      Form  scan_prog
*&---------------------------------------------------------------------*
FORM scan_prog USING    i_devclass   TYPE devclass
                        i_objname    TYPE sobj_name
                        i_cnt_line   TYPE n
               CHANGING i_tab_source TYPE t_tab_long_lines.
  DATA: l_str_source TYPE t_abapsource_long,
*        l_line         TYPE sytabix,
*        l_out_progname TYPE xfeld,   "EC NEEDED
        l_flg_found  TYPE xfeld,
        l_flg_write  TYPE xfeld,
        l_cnt_line   TYPE i,
*        l_modulo       TYPE i,
        l_str_lines  TYPE t_str_lines.

* Initialization
*  CLEAR l_out_progname.
  CLEAR l_flg_found.
  g_line_object = i_objname.
  l_cnt_line = 1000.

  CLEAR l_str_lines.
  l_str_lines-devclass = i_devclass.
  l_str_lines-progname = i_objname.

* Search source for selection criteria
  LOOP AT i_tab_source INTO l_str_source.
    g_line_number = sy-tabix.
    CLEAR l_flg_write.
    IF l_str_source-line CS p_strg1 AND
       ( p_strg2 IS INITIAL OR l_str_source-line CS p_strg2 ).
      IF ( p_excl1 IS INITIAL OR
           NOT l_str_source-line CS p_excl1 ) AND
         ( p_excl2 IS INITIAL OR
           NOT l_str_source-line CS p_excl2 ) AND
         ( p_excl3 IS INITIAL OR
           NOT l_str_source-line CS p_excl3 ) AND
         ( p_excomm IS INITIAL OR
           l_str_source-line(1) <> '*' ).
        l_flg_write = con_true.
        l_cnt_line  = 0.
      ENDIF.
    ENDIF.

    IF l_flg_write = con_true OR l_cnt_line < i_cnt_line.
      l_cnt_line  = l_cnt_line + 1.
      l_flg_found = con_true.
      l_str_lines-linno = g_line_number.
      l_str_lines-line  = l_str_source-line.
      APPEND l_str_lines TO g_tab_lines.
    ENDIF.

  ENDLOOP.

* No hits found
  IF p_nohits = con_true AND l_flg_found IS INITIAL.

    l_str_lines-linno = 1.
    l_str_lines-line  = 'Keine Treffer'(014).
    APPEND l_str_lines TO g_tab_lines.
  ENDIF.

ENDFORM.                    " scan_prog

*&---------------------------------------------------------------------*
*&      Form  scan_prog
*&---------------------------------------------------------------------*
FORM scan_prog2 USING    i_devclass   TYPE devclass
                        i_objname    TYPE sobj_name
                        i_form TYPE string
                        i_cnt_line   TYPE n
               CHANGING i_tab_source TYPE t_tab_long_lines.
  DATA: l_str_source TYPE t_abapsource_long,
*        l_line         TYPE sytabix,
*        l_out_progname TYPE xfeld,   "EC NEEDED
        l_flg_found  TYPE xfeld,
        l_flg_write  TYPE xfeld,
        l_cnt_line   TYPE i,
*        l_modulo       TYPE i,
        l_str_lines  TYPE t_str_lines.

* Initialization
*  CLEAR l_out_progname.
  CLEAR l_flg_found.
  g_line_object = i_objname.
  l_cnt_line = 1000.

  CLEAR l_str_lines.
  l_str_lines-devclass = i_devclass.
  l_str_lines-progname = i_objname.
  l_str_lines-form = i_form.

* Search source for selection criteria
  LOOP AT i_tab_source INTO l_str_source.
    g_line_number = sy-tabix.
    CLEAR l_flg_write.
    IF l_str_source-line CS p_strg1 AND
       ( p_strg2 IS INITIAL OR l_str_source-line CS p_strg2 ).
      IF ( p_excl1 IS INITIAL OR
           NOT l_str_source-line CS p_excl1 ) AND
         ( p_excl2 IS INITIAL OR
           NOT l_str_source-line CS p_excl2 ) AND
         ( p_excl3 IS INITIAL OR
           NOT l_str_source-line CS p_excl3 ) AND
         ( p_excomm IS INITIAL OR
           l_str_source-line(1) <> '*' ).
        l_flg_write = con_true.
        l_cnt_line  = 0.
      ENDIF.
    ENDIF.

    IF l_flg_write = con_true OR l_cnt_line < i_cnt_line.
      l_cnt_line  = l_cnt_line + 1.
      l_flg_found = con_true.
      l_str_lines-linno = g_line_number.
      l_str_lines-line  = l_str_source-line.
      APPEND l_str_lines TO g_tab_lines.
    ENDIF.

  ENDLOOP.

* No hits found
  IF p_nohits = con_true AND l_flg_found IS INITIAL.
    l_str_lines-linno = 1.
    l_str_lines-line  = 'Keine Treffer'(014).
    APPEND l_str_lines TO g_tab_lines.
  ENDIF.

ENDFORM.                    " scan_prog2

*&---------------------------------------------------------------------*
*&      Form  navigate_to_object
*&---------------------------------------------------------------------*
FORM navigate_to_object USING i_objname  TYPE sobj_name
                              i_position TYPE sytabix
                              i_edit     TYPE xfeld.
  DATA: l_operation(5).

* Check object name: object name is filled via HIDE and
* event AT LINE-SELECTION
  IF i_objname IS INITIAL.
    EXIT.
  ENDIF.

* Set edit mode
  l_operation = 'EDIT'.
  IF i_edit <> con_true.
    l_operation = 'SHOW'.
  ENDIF.

* Navigation to current object
  CALL FUNCTION 'RS_TOOL_ACCESS'
    EXPORTING
      operation           = l_operation
      object_name         = i_objname
      object_type         = 'REPS'
*     ENCLOSING_OBJECT    =
*     POSITION            = con_false
      position            = i_position
*     DEVCLASS            =
*     INCLUDE             =
*     VERSION             = con_false
*     MONITOR_ACTIVATION  = con_true
*     WB_MANAGER          =
*     IN_NEW_WINDOW       =
*     WITH_OBJECTLIST     = con_false
* IMPORTING
*     NEW_NAME            =
*     WB_TODO_REQUEST     =
* TABLES
*     OBJLIST             =
    EXCEPTIONS
      not_executed        = 0
      invalid_object_type = 0
      OTHERS              = 0.

ENDFORM.                    " navigate_to_object

*---------------------------------------------------------------------*
*       FORM ALV_USER_COMMAND                                         *
*---------------------------------------------------------------------*
FORM alv_user_command
     USING i_ucomm TYPE syucomm
           i_selfield TYPE slis_selfield.                   "#EC CALLED

  DATA: l_str_lines TYPE t_str_lines,
        l_position  TYPE sytabix.

  l_position = 1.
  READ TABLE g_tab_lines INTO l_str_lines INDEX i_selfield-tabindex.
  IF sy-subrc = 0.
    l_position = l_str_lines-linno.
  ENDIF.

  CASE i_ucomm.

    WHEN '&IC1'.
      PERFORM navigate_to_object USING l_str_lines-progname
                                       l_position
                                       p_edit.

  ENDCASE.

* Do refresh always col- and row-stable
  IF i_selfield-refresh = con_true.
    i_selfield-col_stable = con_true.
    i_selfield-row_stable = con_true.
  ENDIF.

ENDFORM.                    "alv_user_command
*&---------------------------------------------------------------------*
*&      Form  SCAN_DEVC_SCRIP
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_U_DEVC  text
*      -->P_U_INDEX  text
*      -->P_U_COUNT  text
*      -->P_U_CNT_LINE  text
*----------------------------------------------------------------------*
FORM scan_devc_scrip  USING    u_devc
                               u_index
                               u_count
                               u_cnt_line.



  DATA: l_tab_tadir     TYPE TABLE OF tadir,
        l_str_tadir     TYPE tadir,
        l_cnt           TYPE i,
        l_cnt_str(10)   TYPE c,
        l_idx_devc(10)  TYPE c,
        l_cnt_devc(10)  TYPE c,
        l_aux_devc(20)  TYPE c,
        l_percentage    TYPE p,
        l_tabix_str(10) TYPE c,
        l_incl          TYPE sobj_name,
        l_rep_name      TYPE sobj_name,
        l_tab_source    TYPE t_tab_long_lines,    "CB
        l_text          TYPE itex132.

  DATA lt_data TYPE TABLE OF tline.
  DATA ls_data TYPE tline.
  DATA l_element TYPE c LENGTH 10.

  DATA: l_str_source TYPE t_abapsource_long,
        l_flg_found  TYPE xfeld,
        l_flg_write  TYPE xfeld,
        l_cnt_line   TYPE i,
        l_str_lines  TYPE t_str_lines.

* Initialization
  l_idx_devc = u_index.
  l_cnt_devc = u_count.
  CONCATENATE l_idx_devc '/' l_cnt_devc INTO l_aux_devc.
  CONDENSE l_aux_devc.

* Get programs of current package
  REFRESH l_tab_tadir.
  IF u_devc <> c_devc_tmp.
    SELECT * FROM tadir INTO TABLE l_tab_tadir
      WHERE pgmid    = 'R3TR' AND
            object   = 'FORM' AND
            devclass = u_devc AND
            obj_name IN s_rest.                       "#EC CI_SGLSELECT

  ELSE.
    SELECT * FROM tadir INTO TABLE l_tab_tadir
      WHERE pgmid    = 'R3TR' AND
            object   = 'FORM' AND
            devclass = u_devc AND
            author   = sy-uname AND
            obj_name IN s_rest.                       "#EC CI_SGLSELECT
  ENDIF.

* Ignore invalid TADIR entries.
  DELETE l_tab_tadir WHERE obj_name IS INITIAL.

* Write count of programs into list
  DESCRIBE TABLE l_tab_tadir LINES l_cnt.
  IF l_cnt = 0.
    EXIT.
  ENDIF.

* Process all program sources
  l_cnt_str = l_cnt.
  CONDENSE l_cnt_str.
  LOOP AT l_tab_tadir INTO l_str_tadir.
    l_tabix_str = sy-tabix.
    CONDENSE l_tabix_str.

*   Display progress indicator
    l_percentage = 100 * ( sy-tabix / l_cnt ).
    CONCATENATE 'Scanne Paket'(008) u_devc l_aux_devc
                '(' 'Report'(009) l_tabix_str 'von'(010) l_cnt_str ')'
                INTO l_text SEPARATED BY space.
    CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
      EXPORTING
        percentage = l_percentage
        text       = l_text.


    REFRESH lt_data.

    DATA l_form TYPE itcta-tdform.

    l_form = l_str_tadir-obj_name.

    CALL FUNCTION 'READ_FORM'
      EXPORTING
*       CLIENT     = SY-MANDT
        form       = l_form
*       LANGUAGE   = SY-LANGU
*       OLANGUAGE  = ' '
*       OSTATUS    = ' '
*       STATUS     = ' '
*       THROUGHCLIENT          = ' '
*       READ_ONLY_HEADER       = ' '
*       THROUGHLANGUAGE        = ' '
* IMPORTING
*       FORM_HEADER            =
*       FOUND      =
*       HEADER     =
*       OLANGUAGE  =
      TABLES
        form_lines = lt_data
*       PAGES      =
*       PAGE_WINDOWS           =
*       PARAGRAPHS =
*       STRINGS    =
*       TABS       =
*       WINDOWS    =
      .

* Initialization
*  CLEAR l_out_progname.
    CLEAR l_flg_found.
    g_line_object = l_form.
    l_cnt_line = 1000.

    CLEAR l_str_lines.
    l_str_lines-devclass = u_devc.


* Search source for selection criteria
    LOOP AT lt_data INTO l_str_source.
      g_line_number = sy-tabix.
      CLEAR l_flg_write.
      IF l_str_source-line(2) = '/W'.
        l_element = l_str_source-line+2(10).
      ENDIF.
      IF l_str_source-line CS p_strg1 AND
         ( p_strg2 IS INITIAL OR l_str_source-line CS p_strg2 ).
        IF ( p_excl1 IS INITIAL OR
             NOT l_str_source-line CS p_excl1 ) AND
           ( p_excl2 IS INITIAL OR
             NOT l_str_source-line CS p_excl2 ) AND
           ( p_excl3 IS INITIAL OR
             NOT l_str_source-line CS p_excl3 ) AND
           ( p_excomm IS INITIAL OR
             l_str_source-line(1) <> '*' ).
          l_flg_write = con_true.
          l_cnt_line  = 0.
        ENDIF.
      ENDIF.

      IF l_flg_write = con_true OR l_cnt_line < u_cnt_line. l_cnt_line = l_cnt_line + 1. l_flg_found = con_true. l_str_lines-linno = g_line_number. l_str_lines-line = l_str_source-line. l_str_lines-progname = l_form. l_str_lines-form = l_element. APPEND l_str_lines TO g_tab_lines. ENDIF. ENDLOOP. * No hits found IF p_nohits = con_true AND l_flg_found IS INITIAL. l_str_lines-linno = 1. l_str_lines-line = 'Keine Treffer'(014). APPEND l_str_lines TO g_tab_lines. ENDIF. ENDLOOP. ENDFORM. *&---------------------------------------------------------------------* *& Form SCAN_DEVC_SMART *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * -->P_U_DEVC  text
*      -->P_U_INDEX  text
*      -->P_U_COUNT  text
*      -->P_U_CNT_LINE  text
*----------------------------------------------------------------------*
FORM scan_devc_smart  USING    u_devc
                               u_index
                               u_count
                               u_cnt_line.

  DATA: l_tab_tadir     TYPE TABLE OF tadir,
        l_str_tadir     TYPE tadir,
        l_tab_e071      TYPE TABLE OF e071,
        l_str_e071      TYPE e071,
        l_str_tfdir     TYPE tfdir,
        l_cnt           TYPE i,
        l_cnt_str(10)   TYPE c,
        l_idx_devc(10)  TYPE c,
        l_cnt_devc(10)  TYPE c,
        l_aux_devc(20)  TYPE c,
        l_percentage    TYPE p,
        l_tabix_str(10) TYPE c,
        l_rep_name      TYPE sobj_name,
        l_tab_source    TYPE TABLE OF t_abapsource_long,       "CB
        l_text          TYPE itex132.

  DATA l_form TYPE  tdsfname.
  DATA l_formname TYPE  string.
  DATA l_fm_name TYPE  rs38l_fnam.

* Initialization
  l_idx_devc = u_index.
  l_cnt_devc = u_count.
  CONCATENATE l_idx_devc '/' l_cnt_devc INTO l_aux_devc.
  CONDENSE l_aux_devc.

* Get function pools of current package
  REFRESH l_tab_tadir.
  IF u_devc <> c_devc_tmp.
    SELECT * FROM tadir INTO TABLE l_tab_tadir
      WHERE pgmid    = 'R3TR' AND
            object   = 'SSFO' AND
            devclass = u_devc AND
            obj_name IN s_rest.                       "#EC CI_SGLSELECT
  ELSE.
    SELECT * FROM tadir INTO TABLE l_tab_tadir
      WHERE pgmid    = 'R3TR' AND
            object   = 'SSFO' AND
            devclass = u_devc AND
            author   = sy-uname AND
            obj_name IN s_rest.                       "#EC CI_SGLSELECT
  ENDIF.

* Ignore invalid TADIR entries.
  DELETE l_tab_tadir WHERE obj_name IS INITIAL.

* Write count of function pools into list
  DESCRIBE TABLE l_tab_tadir LINES l_cnt.
  IF l_cnt = 0.
    EXIT.
  ENDIF.

* Process all function pools
  l_cnt_str = l_cnt.
  CONDENSE l_cnt_str.
  LOOP AT l_tab_tadir INTO l_str_tadir.

    CLEAR l_fm_name.
    l_form = l_str_tadir-obj_name.
    l_formname = l_str_tadir-obj_name.
    CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
      EXPORTING
        formname           = l_form
      IMPORTING
        fm_name            = l_fm_name
      EXCEPTIONS
        no_form            = 1
        no_function_module = 2
        OTHERS             = 3.

    l_tabix_str = sy-tabix.
    CONDENSE l_tabix_str.

*   Display progress indicator
    l_percentage = 100 * ( sy-tabix / l_cnt ).
    CONCATENATE 'Scanne Paket'(008) u_devc l_aux_devc
                '(' 'FuGr'(011) l_tabix_str 'von'(010) l_cnt_str ')'
                INTO l_text SEPARATED BY space.
    CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
      EXPORTING
        percentage = l_percentage
        text       = l_text.

*   Get function pool objects
*    write: / l_str_tadir-obj_name.
    l_str_e071-pgmid    = 'R3TR'.
    l_str_e071-object   = 'FUGR'.
    l_str_e071-obj_name = l_fm_name.
    REFRESH l_tab_e071.
    CALL FUNCTION 'STOR_RESOLVE_FUGR'
      EXPORTING
        is_e071 = l_str_e071
      TABLES
        tt_e071 = l_tab_e071
      EXCEPTIONS
        OTHERS  = 0.

*   Read basis program sources and search for specified strings
    LOOP AT l_tab_e071 INTO l_str_e071 WHERE object = 'REPO' .
      l_rep_name = l_str_e071-obj_name.
      REFRESH l_tab_source.
      READ REPORT l_rep_name INTO l_tab_source.
      IF sy-subrc = 0.

        PERFORM scan_prog2 USING    u_devc
                                   l_rep_name
                                   l_formname
                                   u_cnt_line
                          CHANGING l_tab_source.       "CB

      ENDIF.
    ENDLOOP .

* (A) Keine generierten Dialoge?!? Das sollte man evtl. optional
*     anbieten (Zeitpunkt-Routinen!)
*   Read function module sources and search for specified strings
    LOOP AT l_tab_e071 INTO l_str_e071 WHERE object = 'FUNC' .
      IF l_str_e071-obj_name(4) = 'VIEW'. "Keine gen. Dialoge
        CONTINUE.
      ENDIF.
      SELECT SINGLE * FROM tfdir INTO l_str_tfdir
        WHERE funcname = l_str_e071-obj_name.         "#EC CI_SGLSELECT
      IF sy-subrc = 0.
        CONCATENATE l_str_tfdir-pname 'U' l_str_tfdir-include
                    INTO l_rep_name.
        REPLACE 'SAPL' WITH 'L' INTO l_rep_name.
        REFRESH l_tab_source.
        READ REPORT l_rep_name INTO l_tab_source.
        IF sy-subrc = 0.

          PERFORM scan_prog2 USING    u_devc
                                     l_rep_name
                                     l_formname
                                     u_cnt_line
                            CHANGING l_tab_source.     "CB

        ENDIF.
      ENDIF.
    ENDLOOP.
  ENDLOOP .

ENDFORM.

*&---------------------------------------------------------------------*
*&      Form  SCAN_DEVC_SMART
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_U_DEVC  text
*      -->P_U_INDEX  text
*      -->P_U_COUNT  text
*      -->P_U_CNT_LINE  text
*----------------------------------------------------------------------*
FORM scan_devc_adobe  USING    u_devc
                               u_index
                               u_count
                               u_cnt_line.

  DATA: l_tab_tadir     TYPE TABLE OF tadir,
        l_str_tadir     TYPE tadir,
        l_tab_e071      TYPE TABLE OF e071,
        l_str_e071      TYPE e071,
        l_str_tfdir     TYPE tfdir,
        l_cnt           TYPE i,
        l_cnt_str(10)   TYPE c,
        l_idx_devc(10)  TYPE c,
        l_cnt_devc(10)  TYPE c,
        l_aux_devc(20)  TYPE c,
        l_percentage    TYPE p,
        l_tabix_str(10) TYPE c,
        l_rep_name      TYPE sobj_name,
        l_tab_source    TYPE TABLE OF t_abapsource_long,       "CB
        l_text          TYPE itex132.

  DATA l_form TYPE  fpname.
  DATA l_formname TYPE  string.
  DATA l_fm_name TYPE  funcname.

* Initialization
  l_idx_devc = u_index.
  l_cnt_devc = u_count.
  CONCATENATE l_idx_devc '/' l_cnt_devc INTO l_aux_devc.
  CONDENSE l_aux_devc.

* Get function pools of current package
  REFRESH l_tab_tadir.
  IF u_devc <> c_devc_tmp.
    SELECT * FROM tadir INTO TABLE l_tab_tadir
      WHERE pgmid    = 'R3TR' AND
            object   = 'SFPF' AND
            devclass = u_devc AND
            obj_name IN s_rest.                       "#EC CI_SGLSELECT
  ELSE.
    SELECT * FROM tadir INTO TABLE l_tab_tadir
      WHERE pgmid    = 'R3TR' AND
            object   = 'SFPF' AND
            devclass = u_devc AND
            author   = sy-uname AND
            obj_name IN s_rest.                       "#EC CI_SGLSELECT
  ENDIF.

* Ignore invalid TADIR entries.
  DELETE l_tab_tadir WHERE obj_name IS INITIAL.

* Write count of function pools into list
  DESCRIBE TABLE l_tab_tadir LINES l_cnt.
  IF l_cnt = 0.
    EXIT.
  ENDIF.

* Process all function pools
  l_cnt_str = l_cnt.
  CONDENSE l_cnt_str.
  LOOP AT l_tab_tadir INTO l_str_tadir.

    CLEAR l_fm_name.
    l_form = l_str_tadir-obj_name.
    l_formname = l_str_tadir-obj_name.
    TRY.
        CALL FUNCTION 'FP_FUNCTION_MODULE_NAME'
          EXPORTING
            i_name     = l_form
          IMPORTING
            e_funcname = l_fm_name.
      CATCH cx_fp_api_repository.
        CONTINUE.
      CATCH     cx_fp_api_usage.
        CONTINUE.
      CATCH     cx_fp_api_internal.
        CONTINUE.
    ENDTRY.
    l_tabix_str = sy-tabix.
    CONDENSE l_tabix_str.

*   Display progress indicator
    l_percentage = 100 * ( sy-tabix / l_cnt ).
    CONCATENATE 'Scanne Paket'(008) u_devc l_aux_devc
                '(' 'FuGr'(011) l_tabix_str 'von'(010) l_cnt_str ')'
                INTO l_text SEPARATED BY space.
    CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
      EXPORTING
        percentage = l_percentage
        text       = l_text.

*   Get function pool objects
*    write: / l_str_tadir-obj_name.
    l_str_e071-pgmid    = 'R3TR'.
    l_str_e071-object   = 'FUGR'.
    l_str_e071-obj_name = l_fm_name.
    REFRESH l_tab_e071.
    CALL FUNCTION 'STOR_RESOLVE_FUGR'
      EXPORTING
        is_e071 = l_str_e071
      TABLES
        tt_e071 = l_tab_e071
      EXCEPTIONS
        OTHERS  = 0.

*   Read basis program sources and search for specified strings
    LOOP AT l_tab_e071 INTO l_str_e071 WHERE object = 'REPO' .
      l_rep_name = l_str_e071-obj_name.
      REFRESH l_tab_source.
      READ REPORT l_rep_name INTO l_tab_source.
      IF sy-subrc = 0.

        PERFORM scan_prog2 USING    u_devc
                                   l_rep_name
                                   l_formname
                                   u_cnt_line
                          CHANGING l_tab_source.       "CB
      ENDIF.
    ENDLOOP .

* (A) Keine generierten Dialoge?!? Das sollte man evtl. optional
*     anbieten (Zeitpunkt-Routinen!)
*   Read function module sources and search for specified strings
    LOOP AT l_tab_e071 INTO l_str_e071 WHERE object = 'FUNC' .
      IF l_str_e071-obj_name(4) = 'VIEW'. "Keine gen. Dialoge
        CONTINUE.
      ENDIF.
      SELECT SINGLE * FROM tfdir INTO l_str_tfdir
        WHERE funcname = l_str_e071-obj_name.         "#EC CI_SGLSELECT
      IF sy-subrc = 0.
        CONCATENATE l_str_tfdir-pname 'U' l_str_tfdir-include
                    INTO l_rep_name.
        REPLACE 'SAPL' WITH 'L' INTO l_rep_name.
        REFRESH l_tab_source.
        READ REPORT l_rep_name INTO l_tab_source.
        IF sy-subrc = 0.

          PERFORM scan_prog2 USING    u_devc
                                     l_rep_name
                                     l_formname
                                     u_cnt_line
                            CHANGING l_tab_source.     "CB

        ENDIF.
      ENDIF.
    ENDLOOP.
  ENDLOOP .

ENDFORM.

Result


SAP ABAP Development, SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides

Sapscript search


SAP ABAP Development, SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides

A column is added with sapscript window name. You cannot jump into the code, but will find it easily in SE71. Note that the search is language dependent. You search the sapscript in logon language.

Smartform code search


SAP ABAP Development, SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides

Name of smartform is in the extra column. You see the generated function in program name first column. You can jump into the code to set a break-point. For editing you should use regular transaction SMARTFORMS

Adobe form code search


SAP ABAP Development, SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides

Similar to smartform search. You should use transaction SFP to edit form and interface. But you can set a break-point for debugging.

No comments:

Post a Comment