В функциях (пригодных для повторного применения) анализа и обработки данных во внутренних таблиц необходимо знать лишь часть данных о таблицах: саму таблицу и имена тех полей, которые нужно обрабатывать. Возникает вопросы: «Каким должен быть интерфейс функции?» и «Как типизировать параметры?». Интерфейсы для внутренних таблиц еще не изобрели, поэтому в параметрах функции должна передаваться обрабатываемая таблица и названия полей для обработки.
Передача имена полей через параметры через параметры накладывает ряд ограничений. Любые действия с изменением структуры (переименование или удаление полей) будет требовать особой осторожности, так как в журнале использования поля отображаться не будут. Эта задача является примером, когда требуется определить названия поля структуры.
В общем случае постановка задачи звучит следующим образом: имеется структура LS_STRUCT. Требуется написать функцию, которая по значению поля будет возвращать его имя. То есть, при LS_STRUCT-SOME_FIELD вернет строку с содержимым SOME_FIELD.
Решить данную задачу можно используя RTTS.
Подход заключается в следующем:
- Определяем структуру для анализа
- Раскладываем структуру на компоненты: поля и группы
- Создаем индексную таблицу со ссылкой на компоненту и информацией о ней
- Для определения имени компоненты по ссылке определяем информацию о поле из таблицы выше
Для примера создадим класс ZCL_STRUCT_ANALYZER
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
CLASS zcl_struct_analyzer DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. METHODS constructor IMPORTING !ir_struct TYPE REF TO data . METHODS get_fieldname IMPORTING !ir_dref TYPE REF TO data RETURNING VALUE(rv_name) TYPE string . PROTECTED SECTION. PRIVATE SECTION. TYPES: BEGIN OF mts_component, dref TYPE REF TO data, name TYPE string, type TYPE REF TO cl_abap_datadescr, END OF mts_component. DATA mht_component TYPE HASHED TABLE OF mts_component WITH UNIQUE KEY dref. ENDCLASS. CLASS ZCL_STRUCT_ANALYZER IMPLEMENTATION. * <SIGNATURE>---------------------------------------------------------------------------------------+ * | Instance Public Method ZCL_STRUCT_ANALYZER->CONSTRUCTOR * +-------------------------------------------------------------------------------------------------+ * | [--->] IR_STRUCT TYPE REF TO DATA * +--------------------------------------------------------------------------------------</SIGNATURE> METHOD constructor. DATA lo_structdescr TYPE REF TO cl_abap_structdescr. DATA lt_component TYPE cl_abap_structdescr=>component_table. DATA ls_component TYPE abap_componentdescr. FIELD-SYMBOLS <ls_struct> TYPE any. FIELD-SYMBOLS <ls_field> TYPE any. FIELD-SYMBOLS <ls_component> TYPE LINE OF cl_abap_structdescr=>component_table. ASSIGN ir_struct->* TO <ls_struct>. ASSERT sy-subrc EQ 0. lo_structdescr ?= cl_abap_tabledescr=>describe_by_data_ref( ir_struct ). lt_component = lo_structdescr->get_components( ). LOOP AT lt_component INTO ls_component WHERE as_include EQ abap_true. lo_structdescr ?= ls_component-type. APPEND LINES OF lo_structdescr->get_components( ) TO lt_component. ENDLOOP. LOOP AT lt_component INTO ls_component WHERE name IS NOT INITIAL OR suffix IS NOT INITIAL. IF ls_component-name IS INITIAL. ls_component-name = ls_component-suffix. ENDIF. ASSIGN COMPONENT ls_component-name OF STRUCTURE <ls_struct> TO <ls_field>. ASSERT sy-subrc EQ 0. INSERT VALUE #( dref = REF #( <ls_field> ) name = ls_component-name type = ls_component-type ) INTO TABLE mht_component. ENDLOOP. ENDMETHOD. * <SIGNATURE>---------------------------------------------------------------------------------------+ * | Instance Public Method ZCL_STRUCT_ANALYZER->GET_FIELDNAME * +-------------------------------------------------------------------------------------------------+ * | [--->] IR_DREF TYPE REF TO DATA * | [<-()] RV_NAME TYPE STRING * +--------------------------------------------------------------------------------------</SIGNATURE> METHOD get_fieldname. READ TABLE mht_component ASSIGNING FIELD-SYMBOL(<ls_compontne>) WITH TABLE KEY dref = ir_dref. ASSERT sy-subrc EQ 0. rv_name = <ls_compontne>-name. ENDMETHOD. ENDCLASS. |
Пример использования
1 2 3 4 5 6 |
DATA ls_mseg TYPE mseg. DATA lo_struct TYPE REF TO zcl_struct_analyzer. lo_struct = NEW #( REF #( ls_mseg ) ). WRITE / lo_struct->get_fieldname( REF #( ls_mseg-vbeln_im ) ). " Вернет VBELN_IM WRITE / lo_struct->get_fieldname( REF #( ls_mseg-vbelp_im ) ). " Вернет VBELP_IM |
Присоединиться к обсуждению...