Перенос данных между различными версиями платформы 1С (например, с 8.1 на 8.2 или 8.3) с использованием конфигурации «Конвертация данных 2.1» — это стандартная, но кропотливая задача. Часто начинающие разработчики сталкиваются с ситуацией, когда вместо списка договоров переносится только один, или теряется связь с основным договором контрагента. В этой статье мы подробно разберем, как избежать «схлопывания» объектов и правильно настроить логику поиска и связей.
Разберем типичную ситуацию: в исходной базе у контрагента «Альфа» есть три договора: «Основной», «Поставка» и «Аренда». После загрузки в базу-приемник вы обнаруживаете, что у контрагента остался только один договор, который постоянно перезаписывается данными последнего обработанного элемента. Выясним причину этого поведения.
Проблема заключается в неправильно настроенных полях поиска в Правиле Конвертации Объекта (ПКО) для справочника ДоговорыКонтрагентов. Если в настройках ПКО на вкладке «Поля поиска» установлены только реквизиты Владелец и ЭтоГруппа, механизм загрузки работает следующим образом:
В результате все договоры одного контрагента «схлопываются» в одну запись. Чтобы этого избежать, необходимо обеспечить уникальность поиска.
Проанализируем способы обеспечения уникальности. Рассмотрим два основных варианта:
Вариант 1. Поиск по внутреннему идентификатору (GUID).
Это самый надежный метод, если базы являются «родственными» (например, одна создана из копии другой). В ПКО на закладке «Настройки» необходимо установить флаг Искать объект приемника по внутреннему идентификатору источника. В этом случае система сначала попытается найти объект по GUID, и только если он не найден, перейдет к полям поиска.
Вариант 2. Поиск по комбинации бизнес-полей.
Если GUID в базах разные, нужно настроить составные поля поиска. Для справочника договоров оптимальной будет комбинация:
Владелец (Контрагент)Код (или Наименование, если коды не уникальны)ЭтоГруппаДля этого в ПКО для соответствующих свойств (например, Код и Владелец) нужно установить флаг «Поиск». Теперь система будет искать договор не просто «какой-нибудь у этого контрагента», а «договор с кодом 001 у этого контрагента».
После того как мы научились переносить все договоры, возникает следующий вопрос: как указать базе-приемнику, какой из этих договоров является основным? Разберем структуру метаданных. В большинстве типовых конфигураций 1С признак «основной» хранится не в самом договоре, а в карточке контрагента. Это реквизит ОсновнойДоговор (или ОсновнойДоговорКонтрагента) справочника Контрагенты.
Ситуация осложняется тем, что возникает циклическая ссылка:
Контрагенты ссылается на ДоговорыКонтрагентов через реквизит ОсновнойДоговор.ДоговорыКонтрагентов ссылается на Контрагенты через реквизит Владелец.Рассмотрим, как «Конвертация данных» справляется с такими зависимостями. При загрузке контрагента система видит ссылку на договор. Если этот договор еще не загружен, система создает «объект-пустышку» (только с заполненными полями поиска) и записывает ссылку на него в реквизит контрагента. Позже, когда очередь дойдет до загрузки самих договоров, эта «пустышка» будет дополнена остальными данными (наименованием, датой и т.д.).
Для реализации этого «один-в-один» выполним следующие шаги:
Контрагенты убедимся, что настроено правило для свойства ОсновнойДоговор.ДоговорыКонтрагентов обязательно должны быть настроены поля поиска (как мы разбирали выше), иначе система не сможет правильно сопоставить «пустышку», созданную при загрузке контрагента, с реальным объектом договора.Иногда требуется более гибкая настройка. Рассмотрим пример кода в обработчике ПоляПоиска в ПКО договора, если мы хотим программно управлять поиском:
// Пример в обработчике "Поля поиска"
Если НомерВариантаПоиска = 1 Тогда
// Пытаемся найти по Коду и Владельцу
ОтключитьСтандартнуюОбработку = Ложь;
ИначеЕсли НомерВариантаПоиска = 2 Тогда
// Если по коду не нашли, пробуем по Наименованию и Владельцу
СсылкаНаОбъект = Справочники.ДоговорыКонтрагентов.НайтиПоНаименованию(СвойстваПоиска["Наименование"], Истина, , СвойстваПоиска["Владелец"]);
КонецЕсли;
Посмотрим на ситуацию, когда в приемнике реквизит основного договора называется иначе. В этом случае в ПКС (Правиле Конвертации Свойства) для контрагента мы просто сопоставляем имя источника и имя приемника. Если же в источнике признак основного договора хранится как-то иначе (например, через регистр сведений или флаг в самом договоре), нам придется использовать обработчик ПослеЗагрузки у Контрагента, чтобы найти нужный договор среди уже загруженных и установить его в качестве основного.
Важный совет по производительности: При переносе больших объемов данных с циклическими ссылками старайтесь использовать поиск по внутреннему идентификатору (GUID). Это значительно ускоряет процесс загрузки, так как системе не требуется выполнять сложные SQL-запросы поиска по нескольким полям (Владелец + Код) для каждой записи.
Таким образом, для успешной конвертации нам необходимо: во-первых, расширить состав полей поиска договора, включив туда Владельца и Код, и во-вторых, правильно настроить передачу ссылочного реквизита в объекте-владельце (Контрагенте).