Написал не так давно метод для выборки во внутреннюю таблицу справочных значений по их ключам с помощью создания динамической программы. К сожалению, исходный код приложить не получится, так как начальство запретило это делать. Так что ограничусь общим описанием теории.
К примеру есть у нас внутренняя таблица:
DATA:
begin of it_BUKRS occurs 0,
BE type T001-BUKRS,
BENAME type T001-BUTXT,
end of it_BUKRS
.
В таблице заполнено поле BE и нам нужно выбрать из T001 значение BUTXT по соответствующему BE и заполнить поле BENAME. Как это нужно сделать «правильно» (т.е. с минимальными затратами памяти и максимально быстро).
- Выберем уникальные значения поля BE;
- Сделаем FOR ALL ENTRIES из T001;
- Пройдем по внутренней таблице и для каждого BE найдем соответствующее значение в выбранных из T001 данных. (Само собой используем HASH-таблицу для ускорения поиска)
И эта последовательность всегда одна и та же.
TYPES:
BEGIN OF s_k1,
BUKRS type T001-BUKRS,
END OF s_k1
.
DATA:
it_k1 TYPE SORTED TABLE OF s_k1 WITH UNIQUE KEY
BUKRS
, wa_k1 like line of it_k1.
FIELD-SYMBOLS:
<fs_1_BUKRS> type ANY,
<fs_1_BUTXT> type ANY
.
"-- Создаем список уникальных значений поля BE
LOOP AT <it_Table> ASSIGNING <wa_Table>.
"--
ASSIGN COMPONENT 'BE'
OF STRUCTURE <wa_Table>
TO <fs_1_BUKRS>.
wa_k1-BUKRS = <fs_1_BUKRS>.
"-- Добавить в список ключей
INSERT wa_k1 INTO TABLE it_k1.
ENDLOOP.
TYPES:
BEGIN OF s_v1,
BUKRS TYPE T001-BUKRS,
BUTXT TYPE T001-BUTXT,
END OF s_v1
.
DATA:
it_v1 TYPE SORTED TABLE OF s_v1 WITH NON-UNIQUE KEY
BUKRS
, wa_v1 like line of it_v1.
"-- Выбираем значения из T001
IF it_k1[] IS INITIAL.
REFRESH it_v1.
ELSE.
SELECT
BUKRS
BUTXT
FROM T001
INTO CORRESPONDING FIELDS OF TABLE it_v1
FOR ALL ENTRIES in it_k1
WHERE BUKRS = it_k1-BUKRS
.
ENDIF.
FREE it_k1.
"-- Присваиваем значения по ключам
LOOP AT <it_Table> ASSIGNING <wa_Table>.
ASSIGN COMPONENT 'BE'
OF STRUCTURE <wa_Table> TO <fs_1_BUKRS>.
ASSIGN COMPONENT 'BENAME'
OF STRUCTURE <wa_Table> TO <fs_1_BUTXT>.
"-- Читаем значение
READ TABLE it_v1 INTO wa_v1
with table key
BUKRS = <fs_1_BUKRS>
.
IF sy-subrc = 0.
<fs_1_BUTXT> = wa_v1-BUTXT.
ELSE.
CLEAR:
<fs_1_BUTXT>
.
ENDIF.
ENDLOOP.
FREE it_v1.
А если у нас всегда выполняются одни и те же действия, то значит стоит сократить их описание до минимума. В частности в данном случае нам нужно указать таблицу из которой нужно выбирать, ключевые поля и поля из которых в которые нужно записать данные.
Т.е. имеем следующую небольшую строку, в которой записана вся суть приведенного выше кода:
'T001{BUKRS=BE}{BUTXT>BENAME}'
.
Передаем в метод строку, указанную выше + нашу внутреннюю таблицу. И после вызова метода поле BENAME будет заполнено соответствующими значениями из T001-BUTXT. Мы сократили наш код, к тому же другому программисту достаточно иметь под рукой справку по методу и он быстро поймет что делает данная строка. При этом весь алгоритм укладывается в небольшую строку.
Для полноценной работы метода добавим в него возможность указывать константы и системные переменные (к примеру sy-langu часто требуется для выборки текстов). Также добавим возможность указания списка команд — тогда мы сможем последовательно выбирать данные.
Как это работает? — с помощью динамических программ. Т.е. метод анализирует переданные через строку параметры, генерирует динамическую программу и запускает её. Добавление программы происходит через «INSERT REPORT l_repid FROM CODE.» чтобы не ограничиваться количеством созданных программ.
P.S. Особо я рад этому методу когда приходится выбирать много значений и периодически уже в процессе работы от постановщика приходит указание на добавление новых поле для выборки.
Автор: shasoft