+ Sapforum.Biz » Инструменты » ABAP - Инструментальные средства » Техники расширений системы SAPТема:
|- 2 - A3_FieldExit: Проверки ведение полей в диалоговых транзакциях



Автор Тема: 2 - A3_FieldExit: Проверки ведение полей в диалоговых транзакциях  (Прочитано 1878 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 674
  • Reputation Power: 2
  • Uukrul barely matters.Uukrul barely matters.
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Использование проверок во время ведение полей в диалоговых транзакциях системы (Техника Field-Exits).

Данная техника, является одной из самых старых в системе и заключается фактически в двух шагах:
  • Создание специального функционального модуля в системе для элемента данных, который присвоен полю экрана в любых диалоговых транзакциях.
  • Активация вызова функционального модуля к полю экрана.

Предпосылки использования техники Field-Exit, следующие: в вашей системе на уровне профиля, должно быть разрешено использование Field-Exit. Для проверки работоспособности Field-Exit, необходимо выполнить транзакцию RZ11 – Ведение профильных параметров и проверить значение параметра abap/fieldexit, рисунок 1: FE-0-1.png. Для проверки состояния параметра, введите имя параметра abap/fieldexit, в поле «Имя параметра» и нажмите кнопку просмотра значений.

Если в системе разрешено использовать расширения для полей экранов то значение данной переменной профиля будет установлено в состояние yes, рисунок 2: FE-0.2.png. Если значение в профиле не определено или же установлено в значение no, то при попытке использования Field-Exit, будет выдаваться сообщение типа ENHANCEMENT с номером 032 – Система не сконфигурирована для полей пользователя (см. подр. текст). Вам следует обратиться к вашему администратору системы SAP, для установки правильного значения системной переменной в профиле системы. Эту процедуру нужно будет повторить для всех систем, т.е. разработки, тестирования и продуктива. Проблем, связанных с установкой данного параметра, я не встречал.

Данная техника расширений работает только в диалоговых транзакциях, т.е. различные функции BAPI пропускают такой тип расширений, но при реализации пакетного ввода, проверка будет выполняться. Данный тип проверки в общем виде предназначен для проверки введенных на экране значений, причем в функциональном модуле проверки, доступ к переменным ограничен, только данными введенными в проверяемом поле. На первый взгляд, область использования, данного типа расширения довольно ограничена, в модуль передается только значение, введенное в поле ввода и на выходе система тоже ожидает только значение, возвращаемое в поле ввода экрана. Однако бывают ситуации когда, даже такая проверка, очень нужна, например контроль ввода данных по маске или контроль значений введенных в полях пользовательских расширений.

Примечание: Ограничение на доступ только к изменяемому полю, в данном типе расширения, можно обойти используя технику FIELD-SYMBOLS, хотя, скорее всего, SAP не будет рекомендовать эту технику обхода, но если очень нужно, это можно использовать. Об этом будет написано в конце раздела.

Для примера использования техники Field-Exits, воспользуемся контролем полей в транзакции ведения инвестиционной программы. В ходе проекта элемент программы должен был содержать кроме стандартно имеющихся, кода БЕ и МВЗ ответственных за реализацию элемента программы, так же содержать код запрашивающей БЕ и МВЗ. К сожалению, транзакция ведения позиции инвестиционной программы не имеет возможностей расширения для добавления пользовательских полей. Разработчики посчитали, что тех 10 пользовательских полей из которых 4 могут быть привязаны к простым справочникам, а остальные достаточно жестко типизированы, должно быть достаточно. Использовать для этого классификацию объектов, оказалось достаточно медленно при построении отчетов по программе. Поэтому решено было использовать одно из пользовательских полей с типом CHAR(20). Однако к данному полю нет привязанного никакого справочника, да к тому же в данное поле предполагалось записывать два значения по маске: «Код БЕ»/«Код МВЗ», поэтому как вариант можно использовать проверку в  Field-Exits.

И так для начала определяем элемент данных, который привязан к переменной, которая в свою очередь привязана к полю экрана. Для этого стандартно в поле экрана нажимаем F1 – Переход к справочной информации к полю и далее переход к техническим параметрам поля, рисунок 3: FE-1.png.  Как видим элемент данных к полю экрана IMPR-USR00, называется IMA_USR00.

Зная имя элемента данных, идем в транзакцию SE38 – редактор кода и запускаем отчет RSMODPRF, который позволяет создать нам функциональный модуль для проверки значений. Запускаем отчет, рисунок 4: FE-2.png.

Вводим имя элемента данных, в поле «№ Поля пользователя» можно ничего не вносить, если мы предполагаем, что экзит будет только один, т.е. в общем виде мы можем сделать различные функции проверки для элемента данных, в зависимости от того для какого поля и на каком экране используется данный элемент. Например, в нашем случае, поле находится в программе SAPLAIP2 на экране 0600, и мы хотим, чтобы вызвался модуль Z, а например если это поле будет находиться на экране 0700, то нужно чтобы вызвался модуль X. Вот для этого и существует определение номера поля пользователя. В нашем случае такой проверки не нужно, поэтому оставляем поле не заполненным.

И так вводим имя элемента данных IMA_USR00 и выполняем отчет. Система переходи к транзакции создания функционального модуля, при этом имя модуля будет сформировано по маске FIELD_EXIT_<Имя элемента данных>, при этом, если бы на предыдущем экране заполнили бы значение в поле «№ поля пользователя», то имя было бы сформировано по маске FIELD_EXIT_<Имя элемента данных>_<Значение введенное в поле № поля пользователя>. Фактически, таким образом, предполагается что вы не будете создавать более 37 различных вариантов функций для проверки значения.

Соглашаемся с предложенным именем функции и переходим к его созданию, выбрав кнопку «Создать», рисунок 5: FE-3.png.

Определяем группу функций и текс описания модуля, рисунок 6: FE-4.png.

Как видим, не смотря на то что имя модуля начинается не с разрешенных типов Z или Y, система разрешила нам выполнить ведение такого модуля. И так на входе нам предлагается переменная INPUT, а на выходе переменная OUTPUT. Типы переменных определяем как элемент данных IMA_USR00, рисунок 7: FE-5.png.

Теперь можно перейти к реализации самой проверки. В данном случае, значение, введенное пользователем в поле, проверяется на то, что первые символы это код БЕ, которая должна существовать, далее идет разделитель в виде слеш «/» после чего идет код МВЗ. Код МВЗ должен существовать в той же контролинговой единице к которой присвоен код балансовой единицы.

Код: You are not allowed to view links. Register or Login
FUNCTION field_exit_ima_usr00.
*"----------------------------------------------------------------------
*"*"Локальный интерфейс:
*"  IMPORTING
*"     REFERENCE(INPUT) TYPE  IMA_USR00
*"  EXPORTING
*"     REFERENCE(OUTPUT) TYPE  IMA_USR00
*"----------------------------------------------------------------------
  DATA: l_bukrs LIKE t001-bukrs,
        l_kostl LIKE csks-kostl,
        l_kokrs TYPE ima_vkokrs,
        l_str1 TYPE string,
        l_str2 TYPE string,
        lt_return LIKE bapiret2 OCCURS 1 WITH HEADER LINE.

* Если значение в поле не задано, тогда проверка не нужна
  IF input = space. EXIT. ENDIF.

  SPLIT input AT '/'(100) INTO l_str1 l_str2.
  CONDENSE: l_str1, l_str2.
  l_bukrs = l_str1.
  l_kostl = l_str2.

* Проверить код БЕ на существование
  SELECT SINGLE bukrs INTO (l_bukrs)
  FROM t001 WHERE bukrs = l_bukrs.

  IF sy-subrc = 0.
*   Получить код КЕ присвоенный к БЕ
    CALL FUNCTION 'RK_KOKRS_FIND'
      EXPORTING
        bukrs                  = l_bukrs
      IMPORTING
        kokrs                  = l_kokrs
      EXCEPTIONS
        assignment_not_allowed = 1
        insufficient_input     = 2
        no_kokrs_assigned      = 3
        no_kokrs_for_bukrs     = 4
        no_kokrs_for_bu_gb     = 5
        wrong_kokrs_for_bukrs  = 6
        wrong_kokrs_for_bu_gb  = 7
        OTHERS                 = 8.
    IF sy-subrc = 0.
      CALL FUNCTION 'AIA_CHECK_EXIST_KOSTL'
        EXPORTING
          i_kostl                = l_kostl
          i_kokrs                = l_kokrs
        TABLES
          return                 = lt_return
        EXCEPTIONS
          no_cost_center         = 1
          no_controlling_area    = 2
          cost_center_not_exists = 3
          OTHERS                 = 4.
      IF sy-subrc <> 0.
        MESSAGE e031 WITH l_kokrs l_kostl.
        EXIT.
      ENDIF.
    ELSE.
      MESSAGE e030 WITH l_bukrs.
      EXIT.
    ENDIF.
  ELSE.
    MESSAGE e029 WITH l_bukrs.
    EXIT.
  ENDIF.

  CONCATENATE l_bukrs '/'(100) l_kostl INTO output SEPARATED BY space.
ENDFUNCTION.

Теперь нужно присвоить вызов нашего модуля  к полю экрана. Для этого снова переходим  отчету RSMODPRF, очищаем ввод от имени нашего элемента данных и снова выполняем отчет. Система покажет нам список и статус всех функциональных модулей типа FIELD_EXIT, которые в настоящий момент созданы в системе. Так как в данной система модуль пока создан только один, то список будет состоять только из одной строки, рисунок 8: FE-6.png.

Первым шагом нужно присвоить функциональный модуль программе и экрану, для которого он будет вызываться. Для этого ставим курсор в строке нашего экзита и отмечаем рядом с именем элемента данных чек-бокс. В строке меню, выбираем кнопку «Присв. Прогр./экран», рисунок 9: FE-7.png

На появившемся экране вводим имя программы и номер экрана, рисунок 10: FE-8.png. Имя программы и номер экрана нужно указать такие же как на рисунке 10: FE-1,png, экран техническая информация, первый на экране блок полей: «Данные экрана». Именно значения выведенные в этом блоке следует использовать на экране ниже.

Так как экзит у нас создавался без номера поля пользователя, то первое поле оставляем пустым, затем выбираем кнопку «Сохранить». Система спросит запрос для транспорта изменений, после чего в списке для нашего экзита появятся заданные нами, программа и экран, рисунок 11: FE-9.png.

Однако, как видим, статус расширения пока неактивен. Для активации нужно выполнить последний шаг, для этого снова выделяем строку экзита, установив чек-бокс рядом в строке, напротив элемента данных и по меню выбираем режим: «Поле пользователя» - «Активировать», рисунок 12: FE-10.png.

Система снова запросит у нас номер запроса, после чего статус экзита изменится на «АКТ.», т.е. данный экзит будет вызываться при обработке значений в заданном нами поле.

Примечание: Доступ к полям транзакции используя технику FIELD-SYMBOLS. В данном случае мы знаем, что наш функциональный модуль работает в контексте программы SAPLAIP2, соответственно мы можем обойти стандартное ограничение видимости переменных и получить доступ к любым глобальным переменным данной программы. Например, мы хотим получить доступ к коду инвестиционной программы и ветке, для которой выполняется ввод данных. Для получения доступа к коду позиции программы, следует написать такой вызов:
Код: You are not allowed to view links. Register or Login
  FIELD-SYMBOLS: <fs_posid> TYPE im_posid.

  <Получить доступ к значению переменной >
  ASSIGN ('(SAPLAIP2)IMPR-POSID') TO <fs_posid>.

  IF sy-subrc = 0.
    <Работа со значением переменной кода позиции программы>

    <Освобождение переменной>
    UNASSIGN <fs_posid>.
  ENDIF.
Т.е. мы получаем доступ к необходимой нам переменной IMPR-POSID в программе SAPLAIP2. Данный способ очень похож на механизмы указателей в других языках. При использовании этого механизма нужно быть осторожным и если не уверены в том, что выполняете, никогда не меняйте значения переменных, а если доступ осуществляется к внутренним таблицам, то никогда не пересортировывайте их, так как это может привести к непредсказуемым результатам.

Данный метод существенно расширяет границы использования техники FIELD_EXIT, так как мы можем получить доступ к контекстным переменным и реализовать любые по сложности проверки ввода для любых полей в стандартных транзакциях системы.

Некоторые проблемы

После переноса программ в продуктивную систему иногда возникает ситуация, что запись FIELD_EXIT-а активна, программа функционального модуля в статусе сгенерировано, но вызов функции не происходит. Тогда следует зайти в отчет управления расширениями RSMODPRF, выполнить его, получить список созданных экзитов и выполнить операцию перегенерации по пути: «Утилиты» – «Перегенерация», рисунок 14: FE-11.png

Перегенерация вызывает две внутренние функции ядра для каждого экзита, которые что-то исправляют в системе. Обычно после этого активные расширения начинают вызываться.
« Последнее редактирование: Январь 31, 2016, 09:40:36 pm от Uukrul »