Универсальный механизм обработки событий записи объектов

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

Комплект поставки: конфигурация, содержащая:

1. Общий модуль «Обработчики событий» — главный модуль

2. Глобальный общий модкль System (библиотека универсальных функций //infostart.ru/public/319157/)

3. Подписки на события перед записью: справочников, документов, задач и др.

Описание работы:

В модуле объекта, перед его записью, можно в дополнительные свойства добавить следующие значения:

1. «ОбязательныеРеквизиты» — Строка реквизитов, разделенных запятой, которые должны быть заполнены. Если хотя бы один из таких реквизитов будет незаполнен, то объект не будет записан (помеченные на удаление объекты не проверяются)

2. «КлючиУникальности» — Строка реквизитов, разделенных запятой, которые должны уникально идентифицировать объект. Если в базе уже будет объект с такими же значениями реквизитов, то объект не будет записан (помеченные на удаление объекты не проверяются и при поиске игнорируются)

3. «ТолькоПредопределенные» — флаг, установка которого запрещает запись непредопределенных элементов (используется для справочников, планов видов характеристик и т.п.; помеченные на удаление объекты не проверяются)

4. «СообщенияПользователю» — массив сообщений, которые нужно показать пользователю

5. «НеВыводитьСообщения» — флаг, запрещающий вывод пользователю сообщений массива «СообщенияПользователю».

Текст модуля:

Процедура ПередЗаписьюСправочника(Источник, Отказ) Экспорт
ТолькоПредопределенные = ПолучитьЗначениеПоКлючу(Источник.ДополнительныеСвойства,"ТолькоПредопределенные",Тип("Булево"));
Если ТолькоПредопределенные и не (Источник.Предопределенный или Источник.ПометкаУдаления) Тогда
Сообщить("Ошибка! В справочнике доступна запись только предопределенных элементов!");
Отказ = Истина;
Иначе
ОбработатьЗаписьОбъекта(Источник,Отказ,"Справочник");
КонецЕсли;
КонецПроцедуры

Процедура ПередЗаписьюДокумента(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
ОбработатьЗаписьОбъекта(Источник,Отказ,"Документ");
КонецПроцедуры

Процедура ПередЗаписьюЗадачи(Источник, Отказ) Экспорт
ОбработатьЗаписьОбъекта(Источник,Отказ,"Задача");
КонецПроцедуры

Процедура ОбработатьЗаписьОбъекта(Источник,Отказ,Класс)
ВыводитьСообщения = не ПолучитьЗначениеПоКлючу(Источник.ДополнительныеСвойства,"НеВыводитьСообщения",Тип("Булево"));
Если ВыводитьСообщения Тогда
СообщенияПользователю = Новый Массив;
Если Источник.ДополнительныеСвойства.Свойство("СообщенияПользователю",СообщенияПользователю) Тогда
Для каждого ЭлементМассива Из СообщенияПользователю Цикл
Сообщить(ЭлементМассива);
КонецЦикла;
КонецЕсли;
КонецЕсли;
ОбязательныеРеквизиты = Неопределено;
Если Источник.ДополнительныеСвойства.Свойство("ОбязательныеРеквизиты",ОбязательныеРеквизиты) Тогда
ДанныеПроверки = ПроверитьЗаполнениеРеквизитов(Источник,ОбязательныеРеквизиты,,ВыводитьСообщения);
Если не ДанныеПроверки.РезультатПроверки Тогда
Отказ = Истина;
Возврат;
КонецЕсли;
КонецЕсли;
КлючиУникальности = Неопределено;
Если Источник.ДополнительныеСвойства.Свойство("КлючиУникальности",КлючиУникальности) Тогда
ЭтоЗадача = Класс = "Задача";
ПутьТаблицы = Источник.Метаданные().ПолноеИмя();
ИмяТаблицы = СтрЗаменить(ПутьТаблицы,".","");
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Ссылка",Источник.Ссылка);
МассивКлючей = ПолучитьМассивКлючей(КлючиУникальности);
ТекстЗапроса =
"ВЫБРАТЬ
| "+ИмяТаблицы+".Ссылка
|ИЗ "+ПутьТаблицы+" КАК "+ИмяТаблицы+"
|ГДЕ
| (НЕ "+ИмяТаблицы+".ПометкаУдаления)"+?(ЭтоЗадача,"
| И (НЕ "+ИмяТаблицы+".Выполнена)","")+"
| И "+ИмяТаблицы+".Ссылка <> &Ссылка";
Для каждого ЭлементМассива Из МассивКлючей Цикл
Если ЗначениеЗаполнено(Источник[ЭлементМассива]) Тогда
Запрос.УстановитьПараметр(ЭлементМассива,Источник[ЭлементМассива]);
ТекстЗапроса = ТекстЗапроса+"
| И "+ИмяТаблицы+"."+ЭлементМассива+" = &"+ЭлементМассива;
КонецЕсли;
КонецЦикла;
Запрос.Текст = ТекстЗапроса;
Если Запрос.Выполнить().Выбрать().Следующий() Тогда
Отказ = Истина;
Если ВыводитьСообщения Тогда
Сообщить("Ошибка! Объект не прошел проверку на уникальность!");
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры

 

 

 

 

 

3 Comments

  1. Agapov_Stas

    И чем это отличается от стандартных механизмов проверки заполнения? В стандартные процедуры проверки передается структура реквизитов для проверки и все корректно проверяется

    Reply
  2. lex27119

    Механизм интересный. Я понял, тут вся соль в том, что события обрабатываются для всех объектов. Интересная задумка

    Reply
  3. alex271

    (1) Agapov_Stas,

    Объясняю.

    Стандартные механизмы требуют гораздо больше кода, а в данном случае все минимизировано.

    Обработка дополнительных свойств осуществляется всего тремя подписками на события и по существу одной процедурой.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *