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