Как в Конвертации данных 2 выгрузить произвольную структуру и подменить ИНН контрагента в зависимости от договора?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При настройке обменов с помощью конфигурации «Конвертация данных 2.0» (КД 2) разработчики часто сталкиваются с ситуацией, когда стандартных механизмов сопоставления «Объект-Источник -> Объект-Приемник» становится недостаточно. Типичный пример: при выгрузке данных из базы 1С 8 в 1С 7.7 необходимо передать контрагента, но его реквизиты (например, ИНН) должны динамически меняться в зависимости от контекста — конкретного договора в документе-источнике.

Если решать эту задачу «в лоб» через стандартное правило конвертации свойств (ПКС) для ИНН, мы столкнемся с проблемой: на уровне конвертации контрагента мы уже «не видим» договор, из которого пришел запрос на выгрузку. Кроме того, повторная выгрузка одного и того же контрагента с разными договорами может затереть данные в приемнике из-за кэширования ссылок.

В этой статье мы подробно разберем, как обойти эти ограничения, правильно передать произвольную структуру данных с помощью функции ВыгрузитьПоПравилу, использовать входящие и исходящие данные, а также избежать перезаписи объектов при загрузке в 1С 7.7.

Причина проблемы: почему стандартная подмена ИНН не работает?

Прежде чем перейти к решениям, проанализируем поведение платформы КД 2. По умолчанию в правилах конвертации объектов (ПКО) включен механизм оптимизации — кэширование ссылок (свойство ЗапомнитьВыгруженныйОбъект). Работает это следующим образом:

  1. При первой встрече контрагента «Ромашка» в документе КД 2 выгружает его, выполняет все обработчики событий и записывает объект в кэш.
  2. При повторном обращении к этому же контрагенту (например, в другой строке документа или в другом документе) КД 2 не выгружает его заново и не выполняет обработчики ПКО/ПКС, а просто возвращает уже готовую ссылку из кэша.

Если для первого договора ИНН должен быть «888», а для второго — «666», то из-за кэширования для обоих договоров выгрузится один и тот же ИНН, обработанный первым. Чтобы решить эту проблему, нам потребуется либо отключить кэширование, либо использовать выгрузку произвольной структуры без жесткой привязки к ссылке источника.

Способ 1. Выгрузка произвольной структуры через ВыгрузитьПоПравилу без Источника

Если нам вообще не нужно передавать ссылку на справочник контрагентов из источника, а требуется лишь передать набор данных (структуру) для создания нового объекта в приемнике, мы можем использовать ПКО с пустым источником.

Разберем по шагам, как это настроить:

  1. Создайте новое ПКО (например, «Получатель_Контрагент»). Поле Источник оставьте пустым (Неопределено), а в поле Приемник выберите справочник «Контрагенты».
  2. В ПКС этого ПКО (например, для свойств «Наименование», «ИНН») установите флажок «Получить из входящих данных».
  3. В документе-источнике (или в любом другом месте, где доступен контекст документа и договора) вызовите выгрузку вручную с помощью встроенной функции ВыгрузитьПоПравилу.

Обратите внимание на важную особенность платформы: при вызове функции ВыгрузитьПоПравилу для ПКО с пустым источником, передаваемые данные регистрируются в третьем параметре — ВходящиеДанные.

Пример кода для выгрузки:


// Формируем структуру с нужными значениями реквизитов
СтруктураДанных = Новый Структура;
СтруктураДанных.Вставить("Наименование", "Ромашка (Договор 1)");

Если ДоговорИсточника.Код = "00001" Тогда
    СтруктураДанных.Вставить("ИНН", "888");
Иначе
    СтруктураДанных.Вставить("ИНН", "666");
КонецЕсли;

// Вызываем выгрузку по нашему правилу
// Обратите внимание: структура передается в третий параметр (ВходящиеДанные)
ВыгрузитьПоПравилу(,, СтруктураДанных,, "Получатель_Контрагент");

При такой схеме КД 2 создаст в файле выгрузки корректный XML-узел для контрагента, заполнив его переданными вручную свойствами.

Способ 2. Использование Исходящих и Входящих данных для передачи контекста

Если ссылка на контрагента нам все же нужна, но внутри ПКО контрагента требуется проанализировать договор, мы можем передать контекст «сверху вниз» — от документа к подчиненному справочнику.

Для этого используется связка локальных переменных ИсходящиеДанные и ВходящиеДанные:

  1. В ПКС документа, где выгружается реквизит «Контрагент», откройте обработчик «Перед выгрузкой».
  2. Определите контекст (договор текущей строки или документа) и поместите его в структуру ИсходящиеДанные:

// Задаем структуру, которая автоматически передастся в подчиненное ПКО контрагента
ИсходящиеДанные = Новый Структура;
Если ОбъектКоллекции.ДоговорКонтрагента.Код = "00001" Тогда
    ИсходящиеДанные.Вставить("ВычисленныйИНН", "888");
Иначе
    ИсходящиеДанные.Вставить("ВычисленныйИНН", "666");
КонецЕсли;
  1. В ПКО Контрагента для свойства «ИНН» взведите флаг «Получить из входящих данных».
  2. В ПКС «ИНН» в обработчике «Перед выгрузкой» напишите код перехвата значения:

Если ВходящиеДанные <> Неопределено И ВходящиеДанные.Свойство("ВычисленныйИНН") Тогда
    Значение = ВходящиеДанные.ВычисленныйИНН;
КонецЕсли;

В данном случае, если входящие данные были переданы из документа, ИНН переопределится. Если контрагент выгружается самостоятельно (вне контекста документа), то выгрузится его стандартный ИНН из базы-источника.

Способ 3. Трансформация Договора в Контрагента

Еще один красивый архитектурный прием — создание ПКО, где Источником выступает Договор, а Приемником — Контрагент. Этот подход решает проблему отсутствия контекста договора на уровне контрагента.

Реализуется это следующим образом:

  1. Создается ПКО «Договор_В_Контрагента» (Источник: ДоговорСсылка, Приемник: СправочникСсылка.Контрагенты).
  2. Внутри этого правила поля заполняются на основании свойств договора и его владельца (Договор.Владелец). Например, в ПКС «ИНН» мы напрямую пишем логику:

Если Источник.Код = "00001" Тогда
    Значение = "888";
Иначе
    Значение = "666";
КонецЕсли;
  1. В ПКС документа, выгружающего контрагента, в качестве правила конвертации указывается именно это ПКО («Договор_В_Контрагента»), а в качестве выгружаемого значения передается сам договор, а не контрагент.

Важные ограничения при загрузке в 1С 7.7

При использовании вышеописанных подходов в обмене с 1С 7.7 необходимо учитывать технические особенности старой платформы:

Применяя эти механизмы управления данными, мы можем гибко настраивать правила интеграции любой сложности, успешно передавая контекст документов в подчиненные справочники КД 2.

← На главную