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