Как это нередко бывает в системе требуются собственные справочники.
Первым делом делается соответствующая таблица ZRATES в транзакции SE11, затем она заполняется данными и используется в нужных разработках (Z-программах, расширениях, средствах поиска и так далее).
Потом уже в связи с тем, что записи надо изменять, включать в перенос – создается ведение таблицы посредством генератора.
Однако рано или поздно надо её отдавать конечному пользователю, а так как проверок в SM30 практически никаких не делается, то вероятность ошибки имеется.
Даже в самой примитивной таблице-справочнике в стиле [код + название] можно делать логические ошибки – добавлять записи с одинаковыми названиями. Ключом понятное дело является Код, а проверка на уникальность стандартно делается только по ключу. Так как же запретить пользователю вводить неверные данные ?
В моём примере справочник будет посложнее:
В рамках некоторого кодового набора в указанием периода (с-по) ведутся некоторые численные показатели.
Поэтому минимально должны проводиться проверки:
- начало периода должно быть меньше конца периода
- диапазоны дат в пределах набора не должны пересекаться
Шаг первый: к таблице ZRATES надо создать ракурс ведения ZV_ZRATES. Прямой ракурс со всеми нужными полями (см Нюанс 1).
Шаг второй: в генераторе ведения выбираем пункт меню Среда – Модификация – События.
Задаём код события [01 = Перед сохранением данных в базе данных] и имя подпрограммы.
Остаётся перейти в редактор и набросать текст программы:
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 sy—subrc.
sort it_zrates by data_set adatu.
data: prev_bdatu like it_zrates—bdatu.
loop at it_zrates.
at new data_set.
prev_bdatu = ‘00000000’.
endat.
if prev_bdatu >= it_zrates—adatu.
message S001(ZFI_SM30) with it_zrates—data_set
prev_bdatu
it_zrates—adatu
it_zrates—bdatu.
l_subrc = 4. exit.
endif.
prev_bdatu = it_zrates—bdatu.
endloop.
move l_subrc to sy—subrc.
endform.
Шаг третий: в тот же инклюд ниже вставляем более простой код проверки одной записи:
MODULE xx_pai_global_check INPUT.
if ZV_ZRATES—adatu > ZV_ZRATES—bdatu.
message E002(ZFI_SM30) with ZV_ZRATES—data_set
ZV_ZRATES—adatu
ZV_ZRATES—bdatu.
endif.
ENDMODULE.
Затем этот модуль надо прописать в экране, то есть добавить строчку MODULE xx_pai_global_check ON CHAIN-REQUEST куда-то в секцию 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_ZRATES—DATA_SET .
FIELD ZV_ZRATES—ADATU .
FIELD ZV_ZRATES—BDATU .
FIELD ZV_ZRATES—KBETR .
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.
Здравствуйте, спасибо за полезную статью. По нюансу № 1 — total можно легко конвертировать в нужный тип :
-Создаём структуру с типом нашей таблицы.
— В loop-e просто присваеваем значение total структуре:
loop at total.
ls_struсt
Приходилось ли когда-нибудь решать более сложную задачу, а именно добавить в сгенерированный ракурс ведения поля из таблиц, не определенных как внешние ключи для полей базовой таблицы?
Не очень представляю, что вы имеете в виду. Но я обычно стараюсь не связываться с усложнением в SM30, особенно если можно сделать своё ведение в ALV.
Наверное самое сложное, что я делал в SM30 за последнюю пару лет — вручную увеличивал ширину таблицы.
Вы хотите не меняя ракурс типа добавлять дескрипшен/детали по коду из связанного справочника? А что вам мешает расширить ракурс?
Поставили задачу создать ракурс ведения, в котором к полям таблицы подтягивались бы еще их названия из других таблиц. Через внешний ключ все такие таблицы не добавишь, а без внешнего ключа они не подтягиваются в ракурс ведения. Вот если бы можно было создать РВ и расширить его своим кодом, экраны модифицировать. Но, как ни пытаюсь, не пускает. То ли оставить как получается, то ли правда отдельную транзакцию делать…
Да, все-таки это можно провернуть: добавить в экран вывода новые поля, а в логику обработки (в частности PAI) свои модули, чтобы их наполнять. Только черт их возьми, зачем заниматься такой ерундой??? Но заказ есть заказ, сделал.