Как правильно перенести несколько договоров контрагента и сохранить признак Основной договор при конвертации данных

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

Перенос данных между различными версиями платформы 1С (например, с 8.1 на 8.2 или 8.3) с использованием конфигурации «Конвертация данных 2.1» — это стандартная, но кропотливая задача. Часто начинающие разработчики сталкиваются с ситуацией, когда вместо списка договоров переносится только один, или теряется связь с основным договором контрагента. В этой статье мы подробно разберем, как избежать «схлопывания» объектов и правильно настроить логику поиска и связей.

Проблема первая: Почему переносится только один договор вместо нескольких?

Разберем типичную ситуацию: в исходной базе у контрагента «Альфа» есть три договора: «Основной», «Поставка» и «Аренда». После загрузки в базу-приемник вы обнаруживаете, что у контрагента остался только один договор, который постоянно перезаписывается данными последнего обработанного элемента. Выясним причину этого поведения.

Проблема заключается в неправильно настроенных полях поиска в Правиле Конвертации Объекта (ПКО) для справочника ДоговорыКонтрагентов. Если в настройках ПКО на вкладке «Поля поиска» установлены только реквизиты Владелец и ЭтоГруппа, механизм загрузки работает следующим образом:

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

В результате все договоры одного контрагента «схлопываются» в одну запись. Чтобы этого избежать, необходимо обеспечить уникальность поиска.

Настройка корректного поиска объектов

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

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

Вариант 2. Поиск по комбинации бизнес-полей.
Если GUID в базах разные, нужно настроить составные поля поиска. Для справочника договоров оптимальной будет комбинация:

Для этого в ПКО для соответствующих свойств (например, Код и Владелец) нужно установить флаг «Поиск». Теперь система будет искать договор не просто «какой-нибудь у этого контрагента», а «договор с кодом 001 у этого контрагента».

Проблема вторая: Как перенести признак «Основной договор»?

После того как мы научились переносить все договоры, возникает следующий вопрос: как указать базе-приемнику, какой из этих договоров является основным? Разберем структуру метаданных. В большинстве типовых конфигураций 1С признак «основной» хранится не в самом договоре, а в карточке контрагента. Это реквизит ОсновнойДоговор (или ОсновнойДоговорКонтрагента) справочника Контрагенты.

Ситуация осложняется тем, что возникает циклическая ссылка:

  1. Справочник Контрагенты ссылается на ДоговорыКонтрагентов через реквизит ОсновнойДоговор.
  2. Справочник ДоговорыКонтрагентов ссылается на Контрагенты через реквизит Владелец.

Алгоритм решения для циклической ссылки

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

Для реализации этого «один-в-один» выполним следующие шаги:

  1. В ПКО Контрагенты убедимся, что настроено правило для свойства ОсновнойДоговор.
  2. В ПКО ДоговорыКонтрагентов обязательно должны быть настроены поля поиска (как мы разбирали выше), иначе система не сможет правильно сопоставить «пустышку», созданную при загрузке контрагента, с реальным объектом договора.
  3. Если вы используете Правила Выгрузки Данных (ПВД), убедитесь, что выгружаются оба справочника. Если выгрузить только договоры через ПВД, реквизит в справочнике контрагентов не обновится сам собой.

Использование обработчиков событий для сложной логики

Иногда требуется более гибкая настройка. Рассмотрим пример кода в обработчике ПоляПоиска в ПКО договора, если мы хотим программно управлять поиском:


// Пример в обработчике "Поля поиска"
Если НомерВариантаПоиска = 1 Тогда
    // Пытаемся найти по Коду и Владельцу
    ОтключитьСтандартнуюОбработку = Ложь; 
ИначеЕсли НомерВариантаПоиска = 2 Тогда
    // Если по коду не нашли, пробуем по Наименованию и Владельцу
    СсылкаНаОбъект = Справочники.ДоговорыКонтрагентов.НайтиПоНаименованию(СвойстваПоиска["Наименование"], Истина, , СвойстваПоиска["Владелец"]);
КонецЕсли;

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

Важный совет по производительности: При переносе больших объемов данных с циклическими ссылками старайтесь использовать поиск по внутреннему идентификатору (GUID). Это значительно ускоряет процесс загрузки, так как системе не требуется выполнять сложные SQL-запросы поиска по нескольким полям (Владелец + Код) для каждой записи.

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

← На главную