Расширения системы (Enhancement Framework). Часть 2
Продолжение. Статья из цикла статей Техники расширений стандартной системы SAP.
Enhancements spot/section – Техника расширения, позволяющая практически выполнить внедрение пользовательского кода в любом месте стандартной бизнес-транз
Продолжение цикла статей "Техники расширений стандартной системы SAP".
Расширения системы (Enhancement Framework). Часть 1 >>
Все статьи цикла приведены внизу публикации.
Пример 1. Возврат результата выполнения стандартного отчета в «свою» программу.
В функциональности ММ, для получения данных по запасам на произвольную дату в прошлых периодах, есть специальный отчет MB5B. Одному из разработчиков потребовалось получить список документов, формирующих остатки, так же как это получает отчет MB5B. Как вариант, можно и самому по таблицам получить такие данные, посмотрев на логику работы отчета, но существует возможность воспользоваться готовым решением. Для этого нам нужно в своей программе вызвать отчет, выполняющийся при вызове транзакции MB5B, например через SUBMIT с параметрами, а затем, после вызова получить данные выбранные отчетом в свою программу. Например, я запустил транзакцию MB5B, с таким вот простым вариантом, Рисунок 17: MB5B.png.
Рис.17: MB5B.png
Скорее всего, программа состоит из блока выбора данных, который в конечном итоге заполняет какую-то внутреннюю таблицу и затем блока, который выводит эту таблицу на экран. Путем работы с отладчиком и кодом отчета, довольно быстро можно найти нужное место, это инклуд RM07MLBD_FORM_02 подпрограмма: «Form LISTAUSGABE1»; теперь если поставить точку останова, то видно, что в данной подпрограмме доступна внутренняя таблица g_t_belege1, которая содержит необходимые данные, Рисунок 18: MB5B-1.png.
Рис.18: MB5B-1.png
Итак, нам надо получить данные этой таблицы в свою программу. Воспользуемся технологией IMPORT/EXPORT и новым предложением от SAP, называемым технология расширений. Идем в транзакцию SE38 и вызываем для просмотра этот модуль. Затем выбираем по меню: "Обработка" – "Операции расширения" – "Показать предполагаемые опции расширения", Рисунок 19: RM07MLBD_FORM_02.png, после чего фактически в каждой подпрограмме будут выделены точки входа, а значит можно туда «вписать» свой код.
Рис.19: RM07MLBD_FORM_02.png
Точки будут подсвечены следующим образом, как на рисунке Рисунок 20: RM07MLBD_FORM_02-ES1.PNG.
Рис.20: RM07MLBD_FORM_02-ES1.PNG
Далее ставим курсор на выбранную точку расширения и выбираем по меню "Программа" – "Расширить" или как на рисунке жмем соответствующую кнопку на панели инструментов (выделено красным). Теперь снова попросим показать точки расширения и должно получиться что-то из Рисунок 21: RM07MLBD_FORM_02-ES2.PNG, т.е. у нас появилась возможность модификации кода программы.
Рис.21: RM07MLBD_FORM_02-ES2.PNG
Затем становимся на нужную нам точку в начале подпрограммы LISTAUSGABE1 (почему в начале, расскажу далее, когда завершим создание точки расширения), и правой кнопкой мыши по контекстному меню выбираем "Enhancement Implemantation" – "Создать расширение", как на рисунке Рисунок 22: RM07MLBD_FORM_02-ES3.PNG.
Рис.22: RM07MLBD_FORM_02-ES3.PNG
В появившемся окне система показывает доступные, так называемые, контейнеры точек расширений, Рисунок 23: ES1.png. Контейнер расширений позволяет сгруппировать несколько созданных нами точек расширений в один блок. Например, нам нужно сделать вставку своего кода в нескольких местах транзакции MB5B: в таком случае, мы создаем контейнер и все созданные точки расширений привязываем к этому контейнеру, это позволяет управлять всеми созданными точками в целом, а не выискивать их по текстам программ. Фактически контейнер несет тот же смысл, что пакеты разработки и запросы.
Нажимаем кнопку «Создать».
Рис.23: ES1.png
Так как мы создаем первую точку расширения, то контейнера для нее еще не существует, поэтому мы заполняем сначала поля: имя точки расширения и краткий комментарий к точке, Рисунок 24: ES2.png.
Рис.24: ES2.png
Затем в поле Composite Enhancement Implementation мы вносим имя нашего контейнера, после чего нажимаем кнопку «Создать» рядом полем, Рисунок 25: ES0.png. Система запросит имя контейнера, краткий текст.
Рис.25: ES0.png
Теперь нажимаем ввод, система спросит пакет разработки и запрос на перенос, после чего возвращаемся в экран точек расширений, жмем там ОК и попадаем в основное окно, в котором уже появилась запись для наших точек, Рисунок 26: ES3.png, выбираем нашу созданную запись, после чего точка расширения будет создана и в коде появится запись расширения, где мы можем вносить свой код.
Рис.26: ES3.png
Какой код следует написать в расширении? Так как мы знаем, что результат выбора находится в таблице G_T_BELEGE1, которая выводится в ALV-таблице, нам нужно написать код, который передаст эту таблицу в память, используя оператор EXPORT. Данные, переданные таким образом, останутся в памяти после завершения отчета и возврата в нашу программу, где эти данные можно считать, используя оператор IMPORT. Правильным будет сделать выход из подпрограммы, так как вызывать ALV смысла нет, данные все равно не будут показываться на экране, поэтому мы сделали свое включение в начале программы, чтобы обойти стандартный вызов отображения данных. Правда при этом, чтобы не нарушить отчет, выход должен быть по какому-то из параметров, я предлагаю сделать имя варианта, например с именем /MYBATH, на экране это будет поле выбора "Вариант просмотра", переменная P_VARI. Фокус в том, что так как наше расширение работает в контексте программы, мы имеем доступ ко всем глобальным переменным программы, поэтому в своей точке можем написать примерно такой код:
*$*$-Start:(1 )------------------------------------------------------------$*$*
ENHANCEMENT 17 YMY_MB5B_EXT. "active version
* Передача параметров для внешних вызовов
IF p_vari = '/MYBATH'.
EXPORT G_T_BELEGE1 TO MEMORY ID 'MYBATH'.
EXIT.
ENDIF.
ENDENHANCEMENT.
*$*$-End: (1 )------------------------------------------------------------$*$*
То, как это выглядит в контексте, показано на Рисунок 27: ES4.png.
Рис.27: ES4.png
Итак, передали в память данные таблицы, затем вышли из подпрограммы без вызова ALV-таблицы. Отчет завершен, в своей программе делаем IMPORT FROM MEMORY ID 'MYBATH' и получаем результат. выполнения отчета Само собой, код нужно активировать, после чего рядом с именем расширения будет добавлена фраза - active version. Скорость работы в этом случае, будет невелика, но если скорость не есть критичный параметр, то вполне можно воспользоваться таким методом для получения расчетных данных без повторения логики работы системы у себя в программах.
Пример 2. Дополнительная проверка полномочий в отчетах по заявкам ММ.
Пример 1 (довольно специфичный) показывает, как выполнять разработку, используя неявную точку расширения, Пример 2 ближе к практике, опишем задачу. Есть отчеты по заявкам на закупку, транзакции:
ME5A - Просмотр списка заявок;
ME5J - Заявки к проекту;
ME5K - Заявки к контировке;
ME5W - Повторная подача заявки.
Разные пользователи создают заявки, как вручную, так и при ППМ, при этом в заявках проставлялась, так называемая, группа допуска, каждый пользователь имел свою группу и соответственно должен был видеть только заявки своей группы допуска или группы ниже его по статусу, т.е. группы допуска были иерархическими структурами. В одной заявке разные позиции, могли принадлежать разным группам допуска. В целом, нужно было организовать дополнительную проверку полномочий для отчетов по заявкам. До версии 6.0 без механизма расширений путь был только один: запрещаем использование стандартных транзакций, отчеты по заявкам и пишем свои. Все остальные варианты вели к модификации кода, что не очень хорошо, с точки зрения поддержки и сопровождения. Однако используя механизм расширений, эту задачу можно решить довольно красиво. В ходе отладки было определено, что все отчеты по заявкам в конечном итоге вызывают один и тот же модуль с подпрограммой START. Пример кода:
Модуль : FM06BF01_START
Со строки : 1
*eject
*----------------------------------------------------------------*
* Listausgabe starten *
*----------------------------------------------------------------*
form start.
*- Daten aus Selektionsreport holen -----------------------------*
import gs_banf from memory id 'GSFRG'.
import cueb from memory id 'XYZ'.
Если хотите прочитать статью полностью и оставить свои комментарии присоединяйтесь к sapland
ЗарегистрироватьсяУ вас уже есть учетная запись?
Войти
Обсуждения 1
Комментарий от
Дмитрий Шулейко
| 20 января 2017, 14:58
Очень доступно описано.
Не совсем к теме статьи, но возможно кому-то будет полезно(возможно тем, у кого версия системы не позволяет использовать ENH):
По пункту "Пример 1. Возврат результата выполнения стандартного отчета в «свою» программу".
Есть стандартный класс, который позволяет получить данные стандартного отчета и использовать их в своей разработке - класс CL_SALV_BS_RUNTIME_INFO.
Технология используется в этотм классе такая же - данные итоговой таблицы отчета записываются в память, и затем вычитываются из памяти.
если использовать этот класс, не придется делать ENH.