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