Расширения в ведении таблиц – транзакция SM30

Как это нередко бывает в системе требуются собственные справочники.

Первым делом делается соответствующая таблица ZRATES в транзакции SE11, затем она заполняется данными и используется в нужных разработках (Z-программах, расширениях, средствах поиска и так далее).

Потом уже в связи с тем, что записи надо изменять, включать в перенос – создается ведение таблицы посредством генератора.

Однако рано или поздно надо её отдавать конечному пользователю, а так как проверок в SM30 практически никаких не делается, то вероятность ошибки имеется.

Даже в самой примитивной таблице-справочнике в стиле [код + название] можно делать логические ошибки – добавлять записи с одинаковыми названиями. Ключом понятное дело является Код, а проверка на уникальность стандартно делается только по ключу. Так как же запретить пользователю вводить неверные данные ?

В моём примере справочник будет посложнее:

image

Пример справочника ZRATES

В рамках некоторого кодового набора в указанием  периода (с-по) ведутся некоторые численные показатели.

Поэтому минимально должны проводиться проверки:

  • начало периода должно быть меньше конца периода
  • диапазоны дат в пределах набора не должны пересекаться

Шаг первый: к таблице ZRATES надо создать ракурс ведения ZV_ZRATES. Прямой ракурс со всеми нужными полями (см Нюанс 1).

Шаг второй: в генераторе ведения выбираем пункт меню Среда – Модификация – События.

Вставка события

Задаём код события [01 = Перед сохранением данных в базе данных] и имя подпрограммы.

Остаётся перейти в редактор и набросать текст программы:

form DO_CHECK

form DO_CHECK.
  data: it_zrates like zrates occurs 0 with header line.
  loop at total.
    move-corresponding total to it_zrates.
    append it_zrates.
  endloop.

  data: l_subrc like sysubrc.

  sort it_zrates by data_set adatu.
  data: prev_bdatu like it_zratesbdatu.

  loop at it_zrates.
    at new data_set.
      prev_bdatu = ‘00000000’.
    endat.

    if prev_bdatu >= it_zratesadatu.
      message S001(ZFI_SM30) with it_zratesdata_set
                                  prev_bdatu
                                  it_zratesadatu
                                  it_zratesbdatu.
      l_subrc = 4.  exit.
    endif.

    prev_bdatu = it_zratesbdatu.
  endloop.
  move l_subrc to sysubrc.
endform.

Шаг третий: в тот же инклюд ниже вставляем более простой код проверки одной записи:

MODULE xx_pai_global_check

MODULE xx_pai_global_check INPUT.
  if ZV_ZRATESadatu > ZV_ZRATESbdatu.
    message E002(ZFI_SM30) with ZV_ZRATESdata_set
                                ZV_ZRATESadatu
                                ZV_ZRATESbdatu.
  endif.
ENDMODULE.

 

Затем этот модуль надо прописать в экране, то есть добавить строчку MODULE xx_pai_global_check ON CHAIN-REQUEST куда-то в секцию PAI:

PAI

PROCESS AFTER INPUT.
 MODULE LISTE_EXIT_COMMAND AT EXIT-COMMAND.
 MODULE LISTE_BEFORE_LOOP.
 LOOP AT EXTRACT.
   MODULE LISTE_INIT_WORKAREA.
   CHAIN.
    FIELD ZV_ZRATESDATA_SET .
    FIELD ZV_ZRATESADATU .
    FIELD ZV_ZRATESBDATU .
    FIELD ZV_ZRATESKBETR .
    MODULE xx_pai_global_check ON CHAIN-REQUEST.
    MODULE SET_UPDATE_FLAG ON CHAIN-REQUEST.
   ENDCHAIN.

 

Тестирование прошло успешно. Шаг второй работает как и положено  — при нажатии кнопки “Сохранить”, шаг третий работает при нажатии Enter (после ввода данных в строку – стандартное поведение).

Нюанс №1: Если расширение делать непосредственно на ведении таблицы (а не ракурса), то внутренние таблицы total, extract выглядят не по-человечески и сложнее в общей обработке – данные представлены в виде одной колонки (вроде кластера).

Нюанс №2: Здесь нельзя говорить message E001 или message W001 (выбрасывает в начальное окно SM30). Ошибку надо показать через message S001, а отмену сохранения следует сделать через прямое присвоение sy-subrc.

5 комментариев

  1. Здравствуйте, спасибо за полезную статью. По нюансу № 1 — total можно легко конвертировать в нужный тип :

    -Создаём структуру с типом нашей таблицы.
    — В loop-e просто присваеваем значение total структуре:
    loop at total.
    ls_struсt

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

  3. Не очень представляю, что вы имеете в виду. Но я обычно стараюсь не связываться с усложнением в SM30, особенно если можно сделать своё ведение в ALV.
    Наверное самое сложное, что я делал в SM30 за последнюю пару лет — вручную увеличивал ширину таблицы.
    Вы хотите не меняя ракурс типа добавлять дескрипшен/детали по коду из связанного справочника? А что вам мешает расширить ракурс?

  4. Поставили задачу создать ракурс ведения, в котором к полям таблицы подтягивались бы еще их названия из других таблиц. Через внешний ключ все такие таблицы не добавишь, а без внешнего ключа они не подтягиваются в ракурс ведения. Вот если бы можно было создать РВ и расширить его своим кодом, экраны модифицировать. Но, как ни пытаюсь, не пускает. То ли оставить как получается, то ли правда отдельную транзакцию делать…

  5. Да, все-таки это можно провернуть: добавить в экран вывода новые поля, а в логику обработки (в частности PAI) свои модули, чтобы их наполнять. Только черт их возьми, зачем заниматься такой ерундой??? Но заказ есть заказ, сделал.

Добавить комментарий

Ваш адрес email не будет опубликован.