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