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