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