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