Еще способы группировки в ABAP-среде: итератор и …
В одной из предыдущих статей мы рассматривали различные способы группировки в ABAP. Однако, тот список не был исчерпывающий (и даже текущий – тоже не исчерпывающий), и есть еще, минимум, 2 + 1 (за гранью) способ для группировки.
С помощью паттерна итератор
Не будем здесь приводить детальное описание паттерна итератор (если нужно – дайте знать в комментариях). Но важно сказать, что это поведенческий паттерн; и его назначение предоставить последовательный доступ ко всем элементам составного объекта (в нашем случае – внутренней таблицы), не раскрывая внутреннего представления. Паттерн итератор также называют cursor (и термин cursor уже является ключевым словом для ABAP). С помощью итератора, мы можем одинаковым образом обойти внутреннюю таблицу (какой бы структуры она ни была) и сделать нужные действия: в нашем текущем случае – сгруппировать.
В данном случае мы рассмотрим, простой (и надежный; используемый в том числе продуктивных целях) пример паттерна итератор.
Классический паттерн итератор имеет, как правило, 2 обязательных метода (минимум; могут быть и другие):
1) has_next_element – проверяет есть ли в коллекции еще один элемента
2) get_next_element – получает следующий элемент коллекции.
Однако, в случае группировки: у нас, по сути, существует две коллекции: группировка и сама таблица; поэтому мы добавим ещё методы:
- has_next_group – проверяет есть ли следующая Группа
- get_next_group – переключает контекст для работы в следующей группе
- read_group_key – получает запись с ключом для группы
и для работы с записями внутри группы:
- has_next_row - проверяет есть ли в группе еще элемент
- get_next_line_as_data_ref – получает элемент из группы
Реализация самого итератора находится здесь. Пример использования будет таким (доступен в unit-test):
DATA lt_fi_doc TYPE tt_fi_doc. DATA lt_fi_doc_sum_by_kunnr TYPE tt_fi_doc. _fill_mock( IMPORTING et_fi_doc = lt_fi_doc ). mo_cut->set_in( it = lt_fi_doc )->group_by( EXPORTING iv_f1 = 'KUNNR' ). CLEAR lt_fi_doc_sum_by_kunnr. WHILE mo_cut->has_next_grp( ) EQ abap_true. mo_cut->get_next_grp( ). _calc_sum_in_group( EXPORTING io_tab_group = mo_cut CHANGING ct_fi_doc_sum = lt_fi_doc_sum_by_kunnr ). ENDWHILE.
Пример расчета суммы в группированных позиция через итератор
Какую возможность дает нам паттерн итератор как таковой (общие рекомендации по итератору):
- Доступ к содержимому коллекции и группировки таблицы без раскрытия внутреннего представления
- Для поддержания нескольких активных обходов одной и той коллекции (внутренней таблицы)
- Единообразный итерфейс доступа с целью обхода различных агрегированных структур
Как это влияет именно на abap (в текущей реализации):
- У нас есть один класс, который позволяет группировать и обходить как группы так и записи внутри групп. Его не нужно копировать
Если хотите прочитать статью полностью и оставить свои комментарии присоединяйтесь к sapland
ЗарегистрироватьсяУ вас уже есть учетная запись?
Войти