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