Копание в данных SAP

от автора

В качестве промо-довеска к ранее опубликованной статье приложу немного опыта и исходного кода для специфической аудитории, а именно пользователей SAP. Однажды мне пришлось полгода позаниматься изучением и программированием в этой чудесной системе, а точнее в модуле CRM. Поскольку, с одной стороны, средства для броузинга данных в SAP крайне скудны, а, с другой, я был избалован собственными привычками делать все мышкой, однажды от скуки я занялся любимым делом — «Свободой выборки», но в ABAP & light версии.
В SAPе таблиц какие-то жуткие тысячи штук, а названия у них не самые удобные и очевидные. Нормализация присутствует в изобилии. Поэтому понять, что же лежит в этой записи таблицы, скажем, BUT_000, можно лишь с некоторой натяжкой. Недолго думая, используя богатые средства рефлексии и метапрограммирования древнего как мамонт языка ABAP и сдабривая это всеми любимым alv_grid’ом я «слабал» некий код, позволяющий просматривать значения ссылок едва ли не на любую глубину, используя метаданные связей.
На память, интерфейс z-отчета это не про кассы, о, случайно зашедший! следующий:

  • имя стартовой таблицы
  • дополнительное условие ограничения
  • количество строк

В открывшемся гриде, равно как и во вложенных, двойной клик по «ссылочному» полю проваливается в таблицу. Остальное уже забыл, не исключено, что это не все вкусности.Изучайте, внедряйте рефакторите, надеюсь вы сможете сами. Удачи!

Итак, исходный код на ABAP

*&---------------------------------------------------------------------* *& Report  Z_GREAT_ALV_TMP *& *&---------------------------------------------------------------------* *& *& *&---------------------------------------------------------------------*  REPORT  z_great_alv_tmp.  DATA:       gv_ok             LIKE sy-ucomm,       gv_container      TYPE REF TO cl_gui_custom_container,       gv_container_name TYPE scrfname VALUE 'CONTAINER_ALV',       gv_grid           TYPE REF TO cl_gui_alv_grid,       gt_fieldcat       TYPE lvc_t_fcat,       gs_layout         TYPE lvc_s_layo.  *&---------------------------------------------------------------------* *&  Include           Z_GREAT_ALV_F01 *&---------------------------------------------------------------------*  FORM create_alv   USING       container_name TYPE scrfname   CHANGING       container TYPE REF TO cl_gui_custom_container       grid TYPE REF TO cl_gui_alv_grid.   "если грида еще нет   IF container IS NOT BOUND.      "создать контейнер     CREATE OBJECT container       EXPORTING         container_name = container_name       EXCEPTIONS         OTHERS         = 1.     IF sy-subrc NE 0.     ENDIF.    ENDIF.    IF container IS BOUND.     "создать грид *    if grid is bound. *      free grid. *    endif.      IF grid IS NOT BOUND.       CREATE OBJECT grid         EXPORTING           i_parent = container         EXCEPTIONS           OTHERS   = 1.       PERFORM set_great_handler.     ENDIF.      IF sy-subrc NE 0.     ENDIF.    ENDIF.  ENDFORM.                    "create_alv  *&---------------------------------------------------------------------* *&      Form  set_great_handlers *&---------------------------------------------------------------------* *       text *----------------------------------------------------------------------*  *&---------------------------------------------------------------------* *&      Form  display_alv *&---------------------------------------------------------------------* *       text *----------------------------------------------------------------------* *      -->GRID       text *      -->TAB        text *----------------------------------------------------------------------* FORM display_alv   CHANGING         grid TYPE REF TO cl_gui_alv_grid         tab TYPE ANY TABLE.    IF grid IS BOUND.     "заполнить свойства колонок *    PERFORM prepare_field_catalog CHANGING gt_fieldcat. *     "главный метод для показа грида     CALL METHOD grid->set_table_for_first_display       EXPORTING" i_structure_name = gv_tablename         is_layout                     = gs_layout       CHANGING         it_outtab                     = tab         it_fieldcatalog               = gt_fieldcat       EXCEPTIONS         invalid_parameter_combination = 1         program_error                 = 2         too_many_lines                = 3         OTHERS                        = 4.     IF sy-subrc NE 0.     ENDIF.  *    "обновить данные *    CALL METHOD grid->refresh_table_display *      EXCEPTIONS *        finished       = 1 *        OTHERS         = 2. * *    IF sy-subrc NE 0. *    ENDIF.    ENDIF.  ENDFORM.                    "display_alv  *&---------------------------------------------------------------------* *&      Form  prepare_field_catalog *&---------------------------------------------------------------------* *       text *----------------------------------------------------------------------* *      -->PT_FIELDCAT  text *----------------------------------------------------------------------* FORM prepare_field_catalog   USING     tabname TYPE dd02l-tabname     itab TYPE rs_bool   CHANGING     fieldcat TYPE lvc_t_fcat .    REFRESH fieldcat.    IF itab IS INITIAL.     CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'       EXPORTING         i_structure_name = tabname       CHANGING         ct_fieldcat      = fieldcat       EXCEPTIONS         OTHERS           = 1.     FIELD-SYMBOLS: <fs_fcat> TYPE lvc_s_fcat.     LOOP AT fieldcat ASSIGNING <fs_fcat>.       <fs_fcat>-edit = 'X'.     ENDLOOP.   ELSE.     DATA: lv_field TYPE lvc_s_fcat.      lv_field-fieldname = 'FK_TABNAME'.     lv_field-scrtext_s = 'TABNAME'.     lv_field-inttype = 'C'.     lv_field-outputlen = 50.     APPEND lv_field TO fieldcat.      lv_field-fieldname = 'FIELDNAME'.     lv_field-scrtext_s = 'FIELDNAME'.     lv_field-outputlen = 30.     APPEND lv_field TO fieldcat.    ENDIF.   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.                    "prepare_field_catalog  *&---------------------------------------------------------------------* *&      Form  great_alv *&---------------------------------------------------------------------* *       text *----------------------------------------------------------------------*  *&---------------------------------------------------------------------* *&  Include           Z_GREAT_ALV_CL_DICTSERVICES *&---------------------------------------------------------------------*  CLASS z_cl_great_alv_dictservices DEFINITION.   PUBLIC SECTION.     TYPES:       BEGIN OF z_fk_pair,         pk_name TYPE dd03l-fieldname,         fk_name TYPE dd03l-fieldname,       END OF z_fk_pair,       z_fk_pair_list TYPE STANDARD TABLE OF z_fk_pair,       BEGIN OF z_dependent_rec,         pk_tabname TYPE dd02l-tabname,         fk_tabname TYPE dd02l-tabname,         fieldname TYPE dd03l-fieldname,         frkart TYPE dd08l-frkart,         fieldlist TYPE REF TO data,"z_fk_pair_list,       END OF z_dependent_rec,       z_dependent_rec_list TYPE STANDARD TABLE OF z_dependent_rec.     CLASS-METHODS:       get_fk_list         IMPORTING           tabname TYPE dd02l-tabname           fieldname TYPE dd03l-fieldname         EXPORTING           dependent_rec TYPE z_dependent_rec,       get_check_fk_list         IMPORTING           tabname TYPE dd02l-tabname           fieldname TYPE dd03l-fieldname         EXPORTING           dependent_rec TYPE z_dependent_rec,       get_dependent_list         IMPORTING           tabname TYPE dd02l-tabname         EXPORTING           tablist TYPE z_dependent_rec_list. ENDCLASS.                    "z_cl_great_alv_dictservices DEFINITION  *----------------------------------------------------------------------* *       CLASS z_cl_great_alv_dictservices IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS z_cl_great_alv_dictservices IMPLEMENTATION.   METHOD get_fk_list.      dependent_rec-fk_tabname = tabname.     dependent_rec-fieldname = fieldname.      SELECT SINGLE checktable frkart FROM dd08l INTO (dependent_rec-pk_tabname, dependent_rec-frkart) WHERE tabname = tabname AND fieldname = fieldname.     IF sy-subrc = 0 AND dependent_rec-pk_tabname <> '*'.        DATA: ls_fk_pair TYPE z_fk_pair,             lv_primpos TYPE dd05s-primpos.       FIELD-SYMBOLS: <fs_pair_list> TYPE z_fk_pair_list.       CREATE DATA dependent_rec-fieldlist TYPE z_fk_pair_list.       ASSIGN dependent_rec-fieldlist->* TO <fs_pair_list>.        SELECT primpos forkey FROM dd05s INTO (lv_primpos, ls_fk_pair-fk_name) WHERE tabname = tabname AND fieldname = fieldname.         SELECT SINGLE fieldname FROM dd03l INTO ls_fk_pair-pk_name WHERE tabname = dependent_rec-pk_tabname AND position = lv_primpos.         IF sy-subrc = 0.           APPEND ls_fk_pair TO <fs_pair_list>.         ENDIF.       ENDSELECT.      ENDIF.    ENDMETHOD.                    "get_fk_list    METHOD get_check_fk_list.     dependent_rec-fk_tabname = tabname.     dependent_rec-fieldname = fieldname.      DATA: lv_domname TYPE dd03l-domname.     SELECT SINGLE domname FROM dd03l INTO lv_domname WHERE tabname = tabname AND fieldname = fieldname.     IF sy-subrc = 0 AND lv_domname IS NOT INITIAL.        SELECT SINGLE entitytab FROM dd01l INTO dependent_rec-pk_tabname WHERE domname = lv_domname.       IF sy-subrc = 0 AND dependent_rec-pk_tabname IS NOT INITIAL.          DATA: ls_fk_pair TYPE z_fk_pair.         FIELD-SYMBOLS: <fs_pair_list> TYPE z_fk_pair_list.         CREATE DATA dependent_rec-fieldlist TYPE z_fk_pair_list.         ASSIGN dependent_rec-fieldlist->* TO <fs_pair_list>.          SELECT SINGLE fieldname FROM dd03l INTO ls_fk_pair-pk_name WHERE tabname = dependent_rec-pk_tabname AND domname = lv_domname AND keyflag = 'X'.         IF sy-subrc = 0.           ls_fk_pair-fk_name = fieldname.           APPEND ls_fk_pair TO <fs_pair_list>.         ENDIF.        ENDIF.     ENDIF.   ENDMETHOD.                    "get_check_fk_list    METHOD get_dependent_list.     DATA: ls_rec TYPE z_dependent_rec.     REFRESH tablist.     SELECT tabname fieldname frkart FROM dd08l INTO (ls_rec-fk_tabname, ls_rec-fieldname, ls_rec-frkart) WHERE checktable = tabname.       get_fk_list( EXPORTING         tabname = ls_rec-fk_tabname         fieldname = ls_rec-fieldname       IMPORTING         dependent_rec = ls_rec ).       IF ls_rec-fieldlist IS BOUND.         APPEND ls_rec TO tablist.         CLEAR ls_rec.       ENDIF.     ENDSELECT.   ENDMETHOD.                    "get_dependent_list ENDCLASS.                    "z_cl_great_alv_dictservices IMPLEMENTATION  ** METHOD forward_zalx. **    DATA: **          lv_rowtype TYPE zalx_clnt_genfld-rowtype, **          lv_fkrowtype TYPE zalx_clnt_genfld-fkrowtype, **          lv_fkrowpos TYPE zalx_clnt_genfld-fkrowpos, **          lv_structname TYPE zalx_clnt_genrel-structname, **          lv_tablename TYPE dd02l-tabname, **          lv_condition TYPE string, **          ls_nav_point TYPE z_nav_point. **    READ TABLE nav_stack INTO ls_nav_point INDEX nav_position. **    ls_nav_point-row_id = row_id. **    ls_nav_point-key_field = fieldname. **    MODIFY nav_stack INDEX nav_position FROM ls_nav_point. ** **    IF sy-subrc = 0. **      SELECT SINGLE rowtype FROM zalx_clnt_genrel INTO lv_rowtype WHERE structname = ls_nav_point-tab_name. **      IF sy-subrc = 0. **        SELECT SINGLE fkrowtype fkrowpos FROM zalx_clnt_genfld INTO (lv_fkrowtype, lv_fkrowpos) WHERE rowtype = lv_rowtype AND fieldname = fieldname. **        IF sy-subrc = 0. **          SELECT SINGLE structname FROM zalx_clnt_genrel INTO lv_structname WHERE rowtype = lv_fkrowtype. **          IF sy-subrc = 0. ** **            table_name = lv_structname. **            SELECT SINGLE fieldname FROM zalx_clnt_genfld INTO lv_condition WHERE rowtype = lv_fkrowtype AND rowpos = lv_fkrowpos. **            IF sy-subrc  = 0. **              WRITE lv_structname. **              FIELD-SYMBOLS: <ff> TYPE ANY, **                             <fs> TYPE ANY, **                             <lfs_table> TYPE STANDARD TABLE. ** **              ASSIGN ls_nav_point-tab_table->* TO <lfs_table>. **              READ TABLE <lfs_table> ASSIGNING <fs> INDEX row_id-row_id. **              ASSIGN COMPONENT fieldname OF STRUCTURE <fs> TO <ff>. **              CONCATENATE lv_condition ' = ''' <ff> '''' INTO lv_condition. ** **              CLEAR ls_nav_point. ** **              lv_tablename = lv_structname. **              doselect( EXPORTING tablename = lv_tablename condition = lv_condition **                IMPORTING data_table = ls_nav_point-tab_table ). ** **              data_table = ls_nav_point-tab_table. **              ls_nav_point-tab_name = lv_structname. ** **              APPEND ls_nav_point TO nav_stack. **              ADD 1 TO nav_position. ** **            ENDIF. ** **          ENDIF. ** **        ENDIF. **      ENDIF. **    ENDIF. ** **  ENDMETHOD.                    "forward *&---------------------------------------------------------------------* *&  Include           Z_GREAT_ALV_CL *&---------------------------------------------------------------------*  *&---------------------------------------------------------------------* *&  Include           Z_GREAT_ALV_CL_NAVSTACK *&---------------------------------------------------------------------*  CLASS z_cl_great_alv_navstack DEFINITION.   PUBLIC SECTION.     TYPES:       BEGIN OF z_nav_point,         tab_name TYPE dd02l-tabname,         key_field TYPE lvc_s_col,         row_id TYPE lvc_s_roid,         tab_table TYPE REF TO data,         dependent TYPE rs_bool,       END OF z_nav_point.     CLASS-METHODS:       init         IMPORTING           tablename TYPE dd02l-tabname           reccount TYPE i           condition TYPE string         RETURNING           value(ok) TYPE rs_bool,       follow_fk         IMPORTING           fieldname TYPE lvc_s_col           row_id TYPE lvc_s_roid         RETURNING           value(ok) TYPE rs_bool,       choose_dependent         IMPORTING           fieldname TYPE lvc_s_col           row_id TYPE lvc_s_roid           table_name TYPE dd02l-tabname OPTIONAL         RETURNING           value(ok) TYPE rs_bool,       follow_pk         IMPORTING           deprec TYPE z_cl_great_alv_dictservices=>z_dependent_rec           row_id TYPE lvc_s_roid         RETURNING           value(ok) TYPE rs_bool,       follow_text         IMPORTING           row_id TYPE lvc_s_roid         RETURNING           value(ok) TYPE rs_bool,       back,       current_nav_point RETURNING         value(point) TYPE z_nav_point,       follow_zalx         IMPORTING           fieldname TYPE lvc_s_col           row_id TYPE lvc_s_roid         RETURNING           value(ok) TYPE rs_bool,       get_condition_string IMPORTING         row_id TYPE i         deprec TYPE z_cl_great_alv_dictservices=>z_dependent_rec         data_table TYPE REF TO data OPTIONAL         dependent TYPE rs_bool OPTIONAL         RETURNING value(condition) TYPE string.     PRIVATE SECTION.     CLASS-DATA:       nav_stack TYPE TABLE OF z_nav_point,       nav_position TYPE i,       rec_count TYPE i.     CLASS-METHODS:       doselect         IMPORTING           tablename TYPE dd02l-tabname           condition TYPE string OPTIONAL         EXPORTING           data_table TYPE REF TO data.  ENDCLASS.                    "Z_CL_GREAT_ALV_NAVSTACK DEFINITION  *----------------------------------------------------------------------* *       CLASS Z_CL_GREAT_ALV_NAVSTACK IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS z_cl_great_alv_navstack IMPLEMENTATION.   METHOD init.     REFRESH: nav_stack.     DATA:  ls_nav_point TYPE z_nav_point.     rec_count = reccount.      doselect( EXPORTING tablename = tablename condition = condition       IMPORTING data_table = ls_nav_point-tab_table ).      IF ls_nav_point-tab_table IS BOUND.       ls_nav_point-tab_name = tablename.       APPEND ls_nav_point TO nav_stack.       nav_position = 1.       ok = 'X'.     ENDIF.    ENDMETHOD.                    "init    METHOD doselect.     CREATE DATA data_table TYPE TABLE OF (tablename).     FIELD-SYMBOLS: <fsv_table> TYPE STANDARD TABLE.     ASSIGN data_table->* TO <fsv_table>.      IF condition IS SUPPLIED.       SELECT * UP TO rec_count ROWS FROM (tablename) INTO TABLE <fsv_table> WHERE (condition).     ELSE.       SELECT * UP TO rec_count ROWS FROM (tablename) INTO TABLE <fsv_table>.     ENDIF.   ENDMETHOD.                    "doselect     METHOD follow_fk.      DATA: ls_dep TYPE z_cl_great_alv_dictservices=>z_dependent_rec,           ls_nav_point TYPE z_nav_point,           lv_colname TYPE lvc_s_col,           lv_condition TYPE string.      ls_nav_point = current_nav_point( ).     ls_nav_point-row_id = row_id.     ls_nav_point-key_field = fieldname.     MODIFY nav_stack INDEX nav_position FROM ls_nav_point.      IF ls_nav_point-dependent IS INITIAL.        z_cl_great_alv_dictservices=>get_fk_list( EXPORTING           tabname = ls_nav_point-tab_name           fieldname = fieldname-fieldname         IMPORTING           dependent_rec = ls_dep ).        IF ls_dep-fieldlist IS NOT BOUND.          z_cl_great_alv_dictservices=>get_check_fk_list( EXPORTING             tabname = ls_nav_point-tab_name             fieldname = fieldname-fieldname           IMPORTING             dependent_rec = ls_dep ).        ENDIF.        IF ls_dep-fieldlist IS BOUND.          lv_condition = get_condition_string(           row_id = row_id-row_id           deprec = ls_dep ).          CLEAR ls_nav_point.          doselect( EXPORTING tablename = ls_dep-pk_tabname condition = lv_condition           IMPORTING data_table = ls_nav_point-tab_table ).          IF ls_nav_point-tab_table IS BOUND.           ls_nav_point-tab_name = ls_dep-pk_tabname.            APPEND ls_nav_point TO nav_stack.           ADD 1 TO nav_position.           ok = 'X'.         ENDIF.        ENDIF.      ELSE.        FIELD-SYMBOLS: <fs_dep> TYPE z_cl_great_alv_dictservices=>z_dependent_rec_list.       ASSIGN ls_nav_point-tab_table->* TO <fs_dep>.       IF <fs_dep> IS ASSIGNED.         READ TABLE <fs_dep> INTO ls_dep INDEX row_id-row_id.         IF sy-subrc = 0.           back( ).           ls_nav_point = current_nav_point( ).           lv_colname-fieldname = ls_dep-fieldname.           ok = follow_pk( deprec = ls_dep             row_id = ls_nav_point-row_id              ).         ENDIF.       ENDIF.      ENDIF.    ENDMETHOD.                    "follow_fk    METHOD choose_dependent.     DATA: ls_nav_point TYPE z_nav_point,           lv_dep_list TYPE REF TO data.     FIELD-SYMBOLS <fs_deplist> TYPE z_cl_great_alv_dictservices=>z_dependent_rec_list.     ls_nav_point = current_nav_point( ).     ls_nav_point-row_id = row_id.     ls_nav_point-key_field = fieldname.     MODIFY nav_stack INDEX nav_position FROM ls_nav_point.      CREATE DATA lv_dep_list TYPE z_cl_great_alv_dictservices=>z_dependent_rec_list.     ASSIGN lv_dep_list->* TO <fs_deplist>.     z_cl_great_alv_dictservices=>get_dependent_list(       EXPORTING         tabname = ls_nav_point-tab_name       IMPORTING         tablist = <fs_deplist> ).      IF lv_dep_list IS NOT INITIAL.       SORT <fs_deplist>  BY fk_tabname ASCENDING.       CLEAR ls_nav_point.        ls_nav_point-tab_table = lv_dep_list.       ls_nav_point-dependent = 'X'.        APPEND ls_nav_point TO nav_stack.       ADD 1 TO nav_position.       ok = 'X'.     ENDIF.    ENDMETHOD.                    "choose_dependent    METHOD follow_pk.     DATA: lv_condition TYPE string,           ls_nav_point TYPE z_nav_point.      ls_nav_point = current_nav_point( ).     ls_nav_point-row_id = row_id.     MODIFY nav_stack INDEX nav_position FROM ls_nav_point.      lv_condition = get_condition_string(       row_id = row_id-row_id       deprec = deprec       dependent = 'X' ).      CLEAR ls_nav_point.      doselect( EXPORTING tablename = deprec-fk_tabname       condition = lv_condition       IMPORTING data_table = ls_nav_point-tab_table ).      IF ls_nav_point-tab_table IS BOUND.       ls_nav_point-tab_name = deprec-fk_tabname.        APPEND ls_nav_point TO nav_stack.       ADD 1 TO nav_position.       ok = 'X'.     ENDIF.   ENDMETHOD.                    "follow_pk    METHOD follow_text.     DATA: ls_nav_point TYPE z_nav_point,           lv_colname TYPE lvc_s_col,           lt_dep_list TYPE z_cl_great_alv_dictservices=>z_dependent_rec_list,           ls_dep_list TYPE LINE OF z_cl_great_alv_dictservices=>z_dependent_rec_list.     ls_nav_point = current_nav_point( ).     z_cl_great_alv_dictservices=>get_dependent_list(       EXPORTING         tabname = ls_nav_point-tab_name       IMPORTING         tablist = lt_dep_list ).      LOOP AT lt_dep_list INTO ls_dep_list WHERE frkart = 'TEXT'.       lv_colname-fieldname = ls_dep_list-fieldname.       ok = follow_pk( deprec = ls_dep_list         row_id = row_id          ).       EXIT. "only one text table, if any     ENDLOOP.    ENDMETHOD.                    "follow_text    METHOD back.     IF nav_position > 1.       DELETE nav_stack INDEX nav_position.       SUBTRACT 1 FROM nav_position.     ENDIF.   ENDMETHOD.                    "back    METHOD current_nav_point.     READ TABLE nav_stack INTO point INDEX nav_position.   ENDMETHOD.                    "current_table_name    METHOD get_condition_string.      FIELD-SYMBOLS: <ff> TYPE ANY,                    <fs> TYPE ANY,                    <lfs_table> TYPE STANDARD TABLE,                    <lfs_fkrec> TYPE z_cl_great_alv_dictservices=>z_fk_pair_list.     DATA: ls_navpoint TYPE z_nav_point,           ls_fkpair TYPE z_cl_great_alv_dictservices=>z_fk_pair,           lv_condition TYPE string,           lt_condition TYPE TABLE OF string.     ls_navpoint = current_nav_point( ).     ASSIGN ls_navpoint-tab_table->* TO <lfs_table>.     READ TABLE <lfs_table> ASSIGNING <fs> INDEX row_id.      ASSIGN deprec-fieldlist->* TO <lfs_fkrec>.     LOOP AT <lfs_fkrec> INTO ls_fkpair.       IF dependent IS INITIAL.         ASSIGN COMPONENT ls_fkpair-fk_name OF STRUCTURE <fs> TO <ff>.         CONCATENATE ls_fkpair-pk_name ' = ''' <ff> '''' INTO lv_condition.       ELSE.         ASSIGN COMPONENT ls_fkpair-pk_name OF STRUCTURE <fs> TO <ff>.         CONCATENATE ls_fkpair-fk_name ' = ''' <ff> '''' INTO lv_condition.       ENDIF.       APPEND lv_condition TO lt_condition.     ENDLOOP.      CONCATENATE LINES OF lt_condition INTO condition SEPARATED BY ' AND '.    ENDMETHOD.                    "get_condition_string     METHOD follow_zalx.     DATA:           lv_rowtype TYPE zalx_clnt_genfld-rowtype,           lv_fkrowtype TYPE zalx_clnt_genfld-fkrowtype,           lv_fkrowpos TYPE zalx_clnt_genfld-fkrowpos,           lv_structname TYPE zalx_clnt_genrel-structname,           lv_tablename TYPE dd02l-tabname,           lv_condition TYPE string,           ls_nav_point TYPE z_nav_point.     READ TABLE nav_stack INTO ls_nav_point INDEX nav_position.     ls_nav_point-row_id = row_id.     ls_nav_point-key_field = fieldname.     MODIFY nav_stack INDEX nav_position FROM ls_nav_point.      IF sy-subrc = 0.       SELECT SINGLE rowtype FROM zalx_clnt_genrel INTO lv_rowtype WHERE structname = ls_nav_point-tab_name.       IF sy-subrc = 0.         SELECT SINGLE fkrowtype fkrowpos FROM zalx_clnt_genfld INTO (lv_fkrowtype, lv_fkrowpos) WHERE rowtype = lv_rowtype AND fieldname = fieldname.         IF sy-subrc = 0.           SELECT SINGLE structname FROM zalx_clnt_genrel INTO lv_structname WHERE rowtype = lv_fkrowtype.           IF sy-subrc = 0.              "table_name = lv_structname.             SELECT SINGLE fieldname FROM zalx_clnt_genfld INTO lv_condition WHERE rowtype = lv_fkrowtype AND rowpos = lv_fkrowpos.             IF sy-subrc  = 0.               WRITE lv_structname.               FIELD-SYMBOLS: <ff> TYPE ANY,                              <fs> TYPE ANY,                              <lfs_table> TYPE STANDARD TABLE.                ASSIGN ls_nav_point-tab_table->* TO <lfs_table>.               READ TABLE <lfs_table> ASSIGNING <fs> INDEX row_id-row_id.               ASSIGN COMPONENT fieldname OF STRUCTURE <fs> TO <ff>.               CONCATENATE lv_condition ' = ''' <ff> '''' INTO lv_condition.                CLEAR ls_nav_point.                lv_tablename = lv_structname.               doselect( EXPORTING tablename = lv_tablename condition = lv_condition                 IMPORTING data_table = ls_nav_point-tab_table ).                IF ls_nav_point-tab_table IS BOUND.                 ls_nav_point-tab_name = lv_structname.                  APPEND ls_nav_point TO nav_stack.                 ADD 1 TO nav_position.                 ok = 'X'.               ENDIF.              ENDIF.            ENDIF.          ENDIF.       ENDIF.     ENDIF.    ENDMETHOD.                    "forward ENDCLASS.                    "Z_CL_GREAT_ALV_NAVSTACK IMPLEMENTATION  *----------------------------------------------------------------------* *       CLASS z_great_alv_handler DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS z_great_alv_handler DEFINITION.   PUBLIC SECTION.     CLASS-DATA:       zf_texting TYPE stb_button-function VALUE 'TEXTING',       zf_zalx TYPE stb_button-function VALUE 'ZALX',       zf_depend TYPE stb_button-function VALUE 'DEPEND',       zf_follow TYPE stb_button-function VALUE 'FOLLOW'.     METHODS:       double_click FOR EVENT double_click OF cl_gui_alv_grid         IMPORTING e_row e_column es_row_no,       toolbar_modify FOR EVENT toolbar OF cl_gui_alv_grid         IMPORTING e_object e_interactive,       user_command FOR EVENT user_command OF cl_gui_alv_grid         IMPORTING e_ucomm,       data_changed FOR EVENT data_changed OF cl_gui_alv_grid         IMPORTING er_data_changed e_onf4 e_onf4_before e_onf4_after e_ucomm. ENDCLASS.                    "Z_GREAT_ALV_HANDLER DEFINITION  *----------------------------------------------------------------------* *       CLASS Z_GREAT_ALV_HANDLER IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS z_great_alv_handler IMPLEMENTATION.   METHOD double_click.     DATA: lv_ok TYPE rs_bool.     lv_ok = z_cl_great_alv_navstack=>follow_fk(       fieldname = e_column       row_id = es_row_no ).      IF lv_ok = 'X'.       CALL SCREEN 100.     ENDIF.    ENDMETHOD.                    "DOUBLE_CLICK    METHOD toolbar_modify.     DATA: lv_tbutton TYPE stb_button.      LOOP AT e_object->mt_toolbar INTO lv_tbutton WHERE function = zf_texting.     ENDLOOP.      IF sy-subrc <> 0.        CLEAR lv_tbutton.       MOVE 0 TO lv_tbutton-butn_type.       MOVE zf_follow TO lv_tbutton-function.       MOVE 'Follow foreign key/check table' TO lv_tbutton-text.       MOVE 'Follow foreign key/check table' TO lv_tbutton-quickinfo.       MOVE space TO lv_tbutton-disabled.        APPEND lv_tbutton TO e_object->mt_toolbar.        CLEAR lv_tbutton.       MOVE 0 TO lv_tbutton-butn_type.       MOVE zf_texting TO lv_tbutton-function.       MOVE 'Text table record' TO lv_tbutton-text.       MOVE 'Text table record' TO lv_tbutton-quickinfo.       MOVE space TO lv_tbutton-disabled.        APPEND lv_tbutton TO e_object->mt_toolbar.        CLEAR lv_tbutton.       MOVE 0 TO lv_tbutton-butn_type.       MOVE zf_depend TO lv_tbutton-function.       MOVE 'Dependent tables' TO lv_tbutton-text.       MOVE 'Dependent tables' TO lv_tbutton-quickinfo.       MOVE space TO lv_tbutton-disabled.        APPEND lv_tbutton TO e_object->mt_toolbar.        CLEAR lv_tbutton.       MOVE 0 TO lv_tbutton-butn_type.       MOVE zf_zalx TO lv_tbutton-function.       MOVE 'ZALX' TO lv_tbutton-text.       MOVE 'ZALX' TO lv_tbutton-quickinfo.       MOVE space TO lv_tbutton-disabled.        APPEND lv_tbutton TO e_object->mt_toolbar.      ENDIF.    ENDMETHOD.                    "toolbar_modify    METHOD user_command.      DATA: lv_table  TYPE REF TO data,           lv_column TYPE lvc_s_col,           lv_rowno  TYPE lvc_s_roid,           lv_ok     TYPE rs_bool.     gv_grid->get_current_cell( IMPORTING es_col_id = lv_column       es_row_no = lv_rowno ).      CASE e_ucomm.       WHEN zf_texting.         lv_ok = z_cl_great_alv_navstack=>follow_text(           row_id = lv_rowno ).       WHEN zf_zalx.         lv_ok = z_cl_great_alv_navstack=>follow_zalx(         fieldname = lv_column         row_id = lv_rowno ).       WHEN zf_depend.         lv_ok = z_cl_great_alv_navstack=>choose_dependent(           fieldname = lv_column           row_id = lv_rowno ).       WHEN zf_follow.         lv_ok = z_cl_great_alv_navstack=>follow_fk(         fieldname = lv_column         row_id = lv_rowno ).       WHEN OTHERS.         EXIT.     ENDCASE.      IF lv_ok = 'X'.       CALL SCREEN 100.     ENDIF.    ENDMETHOD.                    "user_command    METHOD data_changed.     DATA: ls_nav_point TYPE z_cl_great_alv_navstack=>z_nav_point,           ls_deleted_row TYPE lvc_s_moce.     FIELD-SYMBOLS: <fst> TYPE STANDARD TABLE,                    <fs> TYPE ANY.     "modify     ls_nav_point = z_cl_great_alv_navstack=>current_nav_point( ).     ASSIGN er_data_changed->mp_mod_rows->* TO <fst>.     MODIFY (ls_nav_point-tab_name) FROM TABLE <fst>.      "delete     ASSIGN ls_nav_point-tab_table->* TO <fst>.     LOOP AT er_data_changed->mt_deleted_rows INTO ls_deleted_row.       READ TABLE <fst> ASSIGNING <fs> INDEX ls_deleted_row-row_id.       IF sy-subrc = 0.         DELETE (ls_nav_point-tab_name) FROM <fs>.       ENDIF.     ENDLOOP.    ENDMETHOD.                    "data_changed  ENDCLASS.                    "Z_GREAT_ALV_HANDLER IMPLEMENTATION  *----------------------------------------------------------------------* *  MODULE PAI_01 INPUT *----------------------------------------------------------------------* * *----------------------------------------------------------------------* MODULE pai_01 INPUT.    CASE gv_ok.     WHEN 'BACK'.       z_cl_great_alv_navstack=>back( ).       PERFORM great_alv.     WHEN '%EX'.       LEAVE PROGRAM.   ENDCASE.  ENDMODULE.                 " PAI_01  INPUT  *----------------------------------------------------------------------* *  MODULE PBO_01 OUTPUT *----------------------------------------------------------------------* * *----------------------------------------------------------------------* MODULE pbo_01 OUTPUT.    CLEAR gv_ok.   SET PF-STATUS ''.   PERFORM great_alv.  ENDMODULE.                 " PBO_01  OUTPUT  *&---------------------------------------------------------------------* *&      Form  set_great_handler *&---------------------------------------------------------------------* *       text *----------------------------------------------------------------------* FORM set_great_handler.   DATA lv_handler TYPE REF TO z_great_alv_handler.   CREATE OBJECT lv_handler.   IF gv_grid IS BOUND AND lv_handler IS BOUND.     SET HANDLER lv_handler->double_click FOR gv_grid.     SET HANDLER lv_handler->toolbar_modify FOR gv_grid.     SET HANDLER lv_handler->user_command FOR gv_grid.     SET HANDLER lv_handler->data_changed FOR gv_grid.     "grid->set_toolbar_interactive( ).   ENDIF. ENDFORM.                    "set_great_handlers  *&---------------------------------------------------------------------* *&      Form  great_alv *&---------------------------------------------------------------------* *       text *----------------------------------------------------------------------* FORM great_alv.    DATA: lv_nav_point TYPE z_cl_great_alv_navstack=>z_nav_point.    lv_nav_point = z_cl_great_alv_navstack=>current_nav_point( ).    PERFORM create_alv USING gv_container_name CHANGING gv_container gv_grid.   .   PERFORM prepare_field_catalog USING lv_nav_point-tab_name lv_nav_point-dependent CHANGING gt_fieldcat.    FIELD-SYMBOLS: <lfs_table> TYPE ANY TABLE.   ASSIGN  lv_nav_point-tab_table->* TO <lfs_table>.    PERFORM display_alv USING gv_grid <lfs_table>.    gv_grid->set_current_cell_via_id( EXPORTING "is_row_no = lv_nav_point-row_id      is_column_id = lv_nav_point-key_field      is_row_no = lv_nav_point-row_id ).  ENDFORM.                    "great_alv    PARAMETERS: tabname LIKE dd02l-tabname DEFAULT 'but050',             rccount TYPE i DEFAULT 100,             condit TYPE string DEFAULT ''.  START-OF-SELECTION.    DATA: lv_ok TYPE rs_bool.    lv_ok = z_cl_great_alv_navstack=>init(       tablename = tabname       reccount = rccount       condition = condit      ).    IF lv_ok = 'X'.     CALL SCREEN 100.   ENDIF.   

ссылка на оригинал статьи http://habrahabr.ru/post/197592/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *