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