В практике разработки на платформе 1С часто возникает задача: выполнить проверку заполнения реквизитов не просто по стандартному алгоритму, а с учетом контекста формы или текущих действий пользователя. Стандартный механизм ОбработкаПроверкиЗаполнения в модуле объекта ограничен своим окружением — он не видит данные формы, которые не связаны с реквизитами объекта (например, переменные формы или состояние элементов управления). В данной статье мы подробно разберем, как передать параметры внутрь этого обработчика, как управлять моментом его вызова и как использовать результаты проверки для изменения визуального состояния формы (например, цвета текста или фона полей).
Давайте проанализируем ситуацию: когда пользователь нажимает кнопку «Записать», платформа автоматически запускает цепочку событий. Важно понимать, что системная проверка заполнения (событие ОбработкаПроверкиЗаполнения в модуле объекта) срабатывает раньше, чем событие формы ПередЗаписьюНаСервере. Это создает сложность: если мы хотим передать какие-то данные из формы в объект непосредственно перед проверкой, мы «опаздываем», так как проверка уже завершилась к моменту выполнения серверного кода формы.
Чтобы решить эту задачу, нам необходимо вмешаться в стандартный алгоритм и перехватить управление. Мы рассмотрим наиболее эффективный способ, который заключается в подавлении автоматической проверки и её ручном запуске в нужный нам момент.
Основным инструментом для передачи «сквозных» параметров в 1С является свойство объекта ДополнительныеСвойства. Это структура, которая существует в оперативной памяти на время жизни экземпляра объекта. Она не сохраняется в базу данных, что делает её идеальным контейнером для передачи временных флагов и настроек.
Разберем, как это работает на практике. Допустим, нам нужно передать в модуль объекта информацию о том, что проверка инициирована именно из формы, и передать значение некоего флага РежимСтрогойПроверки.
Первым делом нам нужно сказать платформе, чтобы она не запускала автоматическую проверку объекта сама по себе. Для этого используем обработчик события формы ОбработкаПроверкиЗаполненияНаСервере. Мы можем либо очистить массив проверяемых реквизитов, либо, что более правильно, установить флаг СтандартнаяОбработка в значение Ложь.
&НаСервере
Процедура ОбработкаПроверкиЗаполненияНаСервере(Отказ, ПроверяемыеРеквизиты)
// Отключаем системный вызов ОбработкаПроверкиЗаполнения в модуле объекта,
// чтобы вызвать его позже вручную с параметрами.
СтандартнаяОбработка = Ложь;
КонецПроцедуры
Теперь, когда автоматический вызов отключен, мы берем управление на себя в процедуре ПередЗаписьюНаСервере. Здесь у нас есть доступ к ТекущийОбъект (экземпляру объекта, который готовится к записи) и мы можем наполнить его ДополнительныеСвойства любыми данными из формы.
&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
// Заполняем параметры для модуля объекта
ТекущийОбъект.ДополнительныеСвойства.Вставить("РежимСтрогойПроверки", Объект.Сумма > 100000);
ТекущийОбъект.ДополнительныеСвойства.Вставить("КонтекстВызова", "ФормаДокумента");
// Вызываем проверку заполнения программно
Если Не ТекущийОбъект.ПроверитьЗаполнение() Тогда
Отказ = Истина;
// Здесь мы можем получить результат обратно из объекта
Если ТекущийОбъект.ДополнительныеСвойства.Свойство("НайденныеОшибки") Тогда
ОбработатьОшибкиДляОформления(ТекущийОбъект.ДополнительныеСвойства.НайденныеОшибки);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Теперь в модуле объекта в процедуре ОбработкаПроверкиЗаполнения мы можем прочитать переданные параметры и изменить состав проверяемых реквизитов или логику валидации. Выясним причину ошибки, основываясь на переданном контексте.
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
// Проверяем наличие наших параметров
СтрогийРежим = Ложь;
Если ДополнительныеСвойства.Свойство("РежимСтрогойПроверки") Тогда
СтрогийРежим = ДополнительныеСвойства.РежимСтрогойПроверки;
КонецЕсли;
Если СтрогийРежим Тогда
// Добавляем дополнительные реквизиты в список обязательных
ПроверяемыеРеквизиты.Добавить("Ответственный");
ПроверяемыеРеквизиты.Добавить("Подразделение");
КонецЕсли;
// Пример ручной проверки с возвратом данных в форму
Если ЗначениеЗаполнено(ЭтотОбъект.Склад) И ЭтотОбъект.Склад.Заблокирован Тогда
Отказ = Истина;
// Сообщаем пользователю
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Выбранный склад недоступен для операций!";
Сообщение.Поле = "Объект.Склад";
Сообщение.УстановитьДанные(ЭтотОбъект);
Сообщение.Сообщить();
// Передаем информацию обратно в форму для условного оформления
СписокОшибок = Новый Массив;
СписокОшибок.Добавить("Склад");
ДополнительныеСвойства.Вставить("НайденныеОшибки", СписокОшибок);
КонецЕсли;
КонецПроцедуры
Одной из интересных задач является «перекрашивание» элементов формы, если проверка не прошла (сообщение 12 из обсуждения). Чтобы реализовать это, мы можем использовать следующий алгоритм:
ДополнительныеСвойства.ПередЗаписьюНаСервере после вызова ПроверитьЗаполнение() считываем этот массив.Рассмотрим подробнее настройку оформления. В редакторе формы перейдите на закладку «Условное оформление» и добавьте новое правило. Укажите цвет текста (например, красный), а в условии укажите: СписокОшибок Содержит "ИмяРеквизита". Теперь, как только ПередЗаписьюНаСервере обновит список ошибок, форма мгновенно изменит свой вид.
Проанализируем важный технический момент: при программном вызове метода ТекущийОбъект.ПроверитьЗаполнение() платформа все равно пытается связать сообщения об ошибках с элементами формы. Чтобы это работало корректно, важно:
СообщениеПользователю.Сообщение.УстановитьДанные(ЭтотОбъект).Объект.ИмяРеквизита (для управляемых форм).Если эти условия соблюдены, то даже при «ручном» запуске проверки пользователь сможет кликнуть по сообщению об ошибке в панели сообщений, и система автоматически активизирует нужное поле на форме, подчеркнув его красным пунктиром.
Если вам требуется перерисовывать форму не в момент записи, а сразу после изменения какого-либо поля (как предлагалось в сообщении 13), вы можете вызвать ту же самую логику из клиентского обработчика ПриИзменении. Для этого создайте серверную процедуру (без контекста или с контекстом), в которой выполните:
&НаСервере
Процедура ПроверитьОбъектНаСервере()
ЭкземплярОбъекта = РеквизитФормыВЗначение("Объект");
ЭкземплярОбъекта.ДополнительныеСвойства.Вставить("ИнтерактивнаяПроверка", Истина);
ЭкземплярОбъекта.ПроверитьЗаполнение();
// Логика обработки результата...
КонецПроцедуры
Такой подход позволяет использовать один и тот же код валидации в модуле объекта как для окончательной проверки перед записью, так и для динамического фидбека пользователю в процессе заполнения документа.
Мы разобрали эффективный способ управления проверкой заполнения в 1С. Ключевые моменты: использование СтандартнаяОбработка = Ложь в форме для перехвата управления, передача контекста через ДополнительныеСвойства и возврат данных об ошибках в форму для реализации механизмов условного оформления. Это позволяет создавать гибкие и отзывчивые интерфейсы, сохраняя при этом бизнес-логику внутри модуля объекта, что соответствует лучшим практикам разработки на платформе 1С:Предприятие.