Данный универсальный механизм в виде набора процедур позволяет решать перечисленные проблемы достаточно быстро.
Комплект поставки: конфигурация, содержащая:
1. Общий модуль «Обработчики событий» — главный модуль
2. Глобальный общий модкль System (библиотека универсальных функций //infostart.ru/public/319157/)
3. Подписки на события перед записью: справочников, документов, задач и др.
Описание работы:
В модуле объекта, перед его записью, можно в дополнительные свойства добавить следующие значения:
1. «ОбязательныеРеквизиты» — Строка реквизитов, разделенных запятой, которые должны быть заполнены. Если хотя бы один из таких реквизитов будет незаполнен, то объект не будет записан (помеченные на удаление объекты не проверяются)
2. «КлючиУникальности» — Строка реквизитов, разделенных запятой, которые должны уникально идентифицировать объект. Если в базе уже будет объект с такими же значениями реквизитов, то объект не будет записан (помеченные на удаление объекты не проверяются и при поиске игнорируются)
3. «ТолькоПредопределенные» — флаг, установка которого запрещает запись непредопределенных элементов (используется для справочников, планов видов характеристик и т.п.; помеченные на удаление объекты не проверяются)
4. «СообщенияПользователю» — массив сообщений, которые нужно показать пользователю
5. «НеВыводитьСообщения» — флаг, запрещающий вывод пользователю сообщений массива «СообщенияПользователю».
Текст модуля:
Процедура ПередЗаписьюСправочника(Источник, Отказ) Экспорт
ТолькоПредопределенные = ПолучитьЗначениеПоКлючу(Источник.ДополнительныеСвойства,"ТолькоПредопределенные",Тип("Булево"));
Если ТолькоПредопределенные и не (Источник.Предопределенный или Источник.ПометкаУдаления) Тогда
Сообщить("Ошибка! В справочнике доступна запись только предопределенных элементов!");
Отказ = Истина;
Иначе
ОбработатьЗаписьОбъекта(Источник,Отказ,"Справочник");
КонецЕсли;
КонецПроцедуры
Процедура ПередЗаписьюДокумента(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
ОбработатьЗаписьОбъекта(Источник,Отказ,"Документ");
КонецПроцедуры
Процедура ПередЗаписьюЗадачи(Источник, Отказ) Экспорт
ОбработатьЗаписьОбъекта(Источник,Отказ,"Задача");
КонецПроцедуры
Процедура ОбработатьЗаписьОбъекта(Источник,Отказ,Класс)
ВыводитьСообщения = не ПолучитьЗначениеПоКлючу(Источник.ДополнительныеСвойства,"НеВыводитьСообщения",Тип("Булево"));
Если ВыводитьСообщения Тогда
СообщенияПользователю = Новый Массив;
Если Источник.ДополнительныеСвойства.Свойство("СообщенияПользователю",СообщенияПользователю) Тогда
Для каждого ЭлементМассива Из СообщенияПользователю Цикл
Сообщить(ЭлементМассива);
КонецЦикла;
КонецЕсли;
КонецЕсли;
ОбязательныеРеквизиты = Неопределено;
Если Источник.ДополнительныеСвойства.Свойство("ОбязательныеРеквизиты",ОбязательныеРеквизиты) Тогда
ДанныеПроверки = ПроверитьЗаполнениеРеквизитов(Источник,ОбязательныеРеквизиты,,ВыводитьСообщения);
Если не ДанныеПроверки.РезультатПроверки Тогда
Отказ = Истина;
Возврат;
КонецЕсли;
КонецЕсли;
КлючиУникальности = Неопределено;
Если Источник.ДополнительныеСвойства.Свойство("КлючиУникальности",КлючиУникальности) Тогда
ЭтоЗадача = Класс = "Задача";
ПутьТаблицы = Источник.Метаданные().ПолноеИмя();
ИмяТаблицы = СтрЗаменить(ПутьТаблицы,".","");
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Ссылка",Источник.Ссылка);
МассивКлючей = ПолучитьМассивКлючей(КлючиУникальности);
ТекстЗапроса =
"ВЫБРАТЬ
| "+ИмяТаблицы+".Ссылка
|ИЗ "+ПутьТаблицы+" КАК "+ИмяТаблицы+"
|ГДЕ
| (НЕ "+ИмяТаблицы+".ПометкаУдаления)"+?(ЭтоЗадача,"
| И (НЕ "+ИмяТаблицы+".Выполнена)","")+"
| И "+ИмяТаблицы+".Ссылка <> &Ссылка";
Для каждого ЭлементМассива Из МассивКлючей Цикл
Если ЗначениеЗаполнено(Источник[ЭлементМассива]) Тогда
Запрос.УстановитьПараметр(ЭлементМассива,Источник[ЭлементМассива]);
ТекстЗапроса = ТекстЗапроса+"
| И "+ИмяТаблицы+"."+ЭлементМассива+" = &"+ЭлементМассива;
КонецЕсли;
КонецЦикла;
Запрос.Текст = ТекстЗапроса;
Если Запрос.Выполнить().Выбрать().Следующий() Тогда
Отказ = Истина;
Если ВыводитьСообщения Тогда
Сообщить("Ошибка! Объект не прошел проверку на уникальность!");
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
И чем это отличается от стандартных механизмов проверки заполнения? В стандартные процедуры проверки передается структура реквизитов для проверки и все корректно проверяется
Механизм интересный. Я понял, тут вся соль в том, что события обрабатываются для всех объектов. Интересная задумка
(1) Agapov_Stas,
Объясняю.
Стандартные механизмы требуют гораздо больше кода, а в данном случае все минимизировано.
Обработка дополнительных свойств осуществляется всего тремя подписками на события и по существу одной процедурой.