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