Как заполнить реквизит документа данными из регистра сведений при конвертации, если основной справочник пуст?

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

При настройке обмена данными между конфигурациями 1С на платформе "Конвертация данных 2.1" часто возникают ситуации, когда архитектура хранения информации в источнике и приемнике кардинально различается. Типичный пример — использование версионирования в базе-источнике. В такой схеме справочник-владелец может быть практически пустым (содержать только ссылку), а все значимые данные (наименование, артикул, параметры) хранятся в подчиненном справочнике "Версии" или в регистре сведений. В базе-приемнике же архитектура может быть упрощена, и данные должны попадать напрямую в основной справочник.

Разберем подробно, как правильно настроить правила обмена (ПКО и ПКС), чтобы документ в приемнике получил корректно заполненную ссылку, "собранную" из данных регистра сведений источника.

Способ 1. Использование переменной "Значение" в ПКС (Наиболее оптимальный)

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

Для реализации этого подхода выполним следующие шаги в настройках ПКС (Правила конвертации свойств) для реквизита Карта в ПКО документа:

  1. Найдем ПКС Карта.
  2. В обработчике Перед выгрузкой напишем код, который находит актуальную версию и подменяет выгружаемый объект.
  3. Укажем в поле "Правило конвертации" то ПКО, которое умеет превращать "Версию карты" (источник) в "Карту" (приемник).

Рассмотрим пример кода в обработчике Перед выгрузкой для ПКС:


// Получаем актуальную версию карты из регистра сведений
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   ВерсииКартСрезПоследних.ВерсияСсылка КАК НужнаяВерсия
    |ИЗ
    |   РегистрСведений.СвязиКарт.СрезПоследних(&Период, Карта = &Карта) КАК ВерсииКартСрезПоследних";

Запрос.УстановитьПараметр("Период", ТекущаяДата());
Запрос.УстановитьПараметр("Карта", Источник.Карта);

РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
    Выборка = РезультатЗапроса.Выбрать();
    Выборка.Следующий();
    
    // Подменяем значение источника. Теперь система будет выгружать 
    // не пустую карту, а найденную версию по правилу, указанному в ПКС.
    Значение = Выборка.НужнаяВерсия;
Иначе
    // Если версия не найдена, можно отменить выгрузку этого свойства
    Отказ = Истина;
КонецЕсли;

Важный момент: При таком подходе в ПКО "Карты" (где источником является СправочникСсылка.ВерсииКарт, а приемником — СправочникСсылка.Карты) вы должны настроить соответствие полей. Например, ПКС Наименование в этом ПКО будет брать данные из Источник.Наименование (где источником выступает версия).

Способ 2. Выгрузка сложного объекта через Структуру (Виртуальный объект)

Если справочник в приемнике очень сложный (содержит множество табличных частей, которые нужно заполнить данными из разных регистров), использование простой подмены ссылки может быть недостаточно. В этом случае мы можем использовать "виртуальный объект" — Структуру.

Рассмотрим ситуацию, когда нам нужно собрать объект Карта "на лету" и передать его в ПКО. В обработчике Перед выгрузкой ПКС документа напишем следующий код:


// Формируем структуру, которая имитирует объект-источник
ДанныеДляВыгрузки = Новый Структура;
ДанныеДляВыгрузки.Вставить("Наименование", "Новая карта из версии");
ДанныеДляВыгрузки.Вставить("Код", "001");

// Заполняем табличную часть (массив структур)
ТЧ_Данные = Новый Массив;
СтрокаТЧ = Новый Структура("Услуга, Количество", СсылкаНаУслугу, 1);
ТЧ_Данные.Добавить(СтрокаТЧ);
ДанныеДляВыгрузки.Вставить("Услуги", ТЧ_Данные);

// Вызываем программную выгрузку по специальному ПКО
// Здесь "КартыВиртуальные" - это ПКО, где Источник не указан (пустой)
Значение = ВыгрузитьПоПравилу(ДанныеДляВыгрузки, , , , "КартыВиртуальные");

В ПКО КартыВиртуальные для каждого ПКС и ПКГС (табличной части) необходимо установить флаг "Получать из входящих данных". Тогда система будет искать ключи в переданной структуре ДанныеДляВыгрузки и сопоставлять их с реквизитами приемника.

Способ 3. Оптимизация через кэширование данных (Срез последних в цикле)

Выясним причину, по которой выгрузка может работать медленно. Если мы делаем запрос к регистру СрезПоследних в каждом документе, то при выгрузке 10 000 документов мы получим 10 000 обращений к БД. Это крайне неэффективно.

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


// В Глобальном модуле или в параметрах создаем Соответствие
Параметры.Вставить("КэшВерсий", Новый Соответствие);

Запрос = Новый Запрос("ВЫБРАТЬ Карта, ВерсияСсылка ИЗ РегистрСведений.СвязиКарт.СрезПоследних");
Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл
    Параметры.КэшВерсий.Вставить(Выборка.Карта, Выборка.ВерсияСсылка);
КонецЦикла;

Теперь в ПКС документа Перед выгрузкой мы не делаем запрос, а просто получаем данные из памяти:


Значение = Параметры.КэшВерсий.Получить(Источник.Карта);
Если Значение = Неопределено Тогда
    Отказ = Истина;
КонецЕсли;

Подмена UUID и поиск объектов

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

Рекомендация: Если вы хотите, чтобы карта в приемнике всегда соответствовала карте в источнике (независимо от того, сколько версий у нее сменилось), используйте для поиска УникальныйИдентификатор самой Карты (владельца), а не версии. Если же при смене версии в источнике в приемнике должна создаваться новая карта, используйте UUID версии.

В ПКО справочника в обработчике Поля поиска можно переопределить стандартную логику, чтобы гарантировать отсутствие дублей при такой сложной схеме "сборки" объекта.

Резюме

Для решения задачи подмены пустого справочника данными из регистра необходимо:

  1. Использовать переменную Значение в ПКС для подстановки ссылки на версию.
  2. Создать отдельное ПКО, где источником будет Версия, а приемником — Карта.
  3. Для сложных структур данных использовать передачу через Структуру и механизм ВходящиеДанные.
  4. Обязательно использовать кэширование через Параметры, чтобы избежать деградации производительности при выполнении запросов в цикле.

Такой подход позволяет гибко управлять данными в процессе конвертации, превращая плоские структуры в иерархические и наоборот, сохраняя при этом целостность ссылочных связей.

← На главную