Рассмотрим распространенную проблему при настройке обмена через конфигурацию «Конвертация данных 2» (КД 2.0). Допустим, мы переносим данные из исторической базы (например, 1С 7.7) в 1С:Управление торговлей 11 (УТ 11). В исходной базе есть только объект Контрагент. В приемнике нам необходимо заполнить реквизит, имеющий составной тип данных (например, поле «Предмет» в заметках), ссылкой на элемент справочника Партнеры. Сложность заключается в том, что система должна сразу знать тип значения при выгрузке, а стандартный поиск по наименованию или ИНН напрямую в Партнерах не работает, так как этих реквизитов там может не быть.
Проанализируем ситуацию подробнее и разберем архитектурные особенности, а затем по шагам выясним, как решить эту задачу несколькими способами.
В конфигурации УТ 11 реализовано разделение на партнеров и контрагентов:
В справочнике «Контрагенты» физически присутствует реквизит Партнер, который связывает юридическое лицо с управленческим объектом. Если в настройках базы-приемника отключен флаг «Независимо вести партнеров и контрагентов», система поддерживает жесткую связь «один к одному».
При выгрузке данных в реквизит составного типа механизм Конвертации Данных требует точного понимания того, к какому типу в приемнике нужно приводить значение. Если мы просто передадим контрагента, а тип поля должен быть СправочникСсылка.Партнеры, перенос завершится ошибкой или поле останется пустым. Решение о типе принимается в момент выгрузки свойства, а не после его загрузки. Поэтому мы не можем просто перенести контрагента, а потом «как-нибудь» подставить партнера.
Разберем самый надежный способ для работы с составными типами — явное указание системе, какое правило и какой тип использовать. Для этого мы задействуем обработчик «Перед выгрузкой» для правила конвертации свойства (ПКС), например, для реквизита «Предмет в заметках».
В коде обработчика пропишем логику определения типа и укажем конкретное правило конвертации:
// Указываем, что в составной реквизит нужно выгрузить именно Партнера
ТипПриемника = "СправочникСсылка.Партнеры";
// Указываем имя специального правила конвертации объектов (ПКО),
// которое будет искать или создавать партнера
ИмяПКО = "Партнеры_ПоискПоКонтрагенту";
Этот подход гарантирует, что XML-узел сформируется с правильным указанием типа, и при загрузке платформа 1С 8.3 не выдаст ошибку несоответствия типов.
Посмотрим на пример, когда мы создаем отдельное Правило Конвертации Объектов (ПКО) для справочника Партнеры, но поле «Источник» оставляем пустым. Это позволяет нам генерировать объект в приемнике на лету, опираясь на переданные параметры.
Партнеры_ПоискПоКонтрагенту, источник — пусто, приемник — СправочникСсылка.Партнеры.ВходящиеДанные.Таким образом, мы передаем параметры в правило с пустым источником, и система обращается к нему для корректной загрузки партнера.
Проанализируем, как найти нужного партнера уже в базе УТ 11, используя переданные данные (например, ИНН и КПП контрагента). Так как у самого Партнера нет ИНН, искать будем через Контрагента, а затем получать его Партнера.
Для этого в созданном ПКО для Партнера перейдем в обработчик «Поля поиска». Код в этом обработчике выполняется в среде приемника (УТ 11), поэтому нам доступны запросы и все объекты метаданных 8-ки.
Напишем произвольный алгоритм поиска:
// Параметры ИНН и КПП получены из входящих данных или свойств поиска
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Контрагенты.Партнер КАК Партнер
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| Контрагенты.ИНН = &ИНН
| И Контрагенты.КПП = &КПП
| И Контрагенты.Партнер <> ЗНАЧЕНИЕ(Справочник.Партнеры.ПустаяСсылка)";
Запрос.УстановитьПараметр("ИНН", СвойстваПоиска.Получить("ИНН"));
Запрос.УстановитьПараметр("КПП", СвойстваПоиска.Получить("КПП"));
РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
// Присваиваем найденную ссылку системной переменной
СсылкаНаПоиск = Выборка.Партнер;
Иначе
// Обработка ситуации, если контрагент или партнер не найден
СсылкаНаПоиск = Неопределено;
КонецЕсли;
При использовании этого метода объект нужного типа (Партнер) будет корректно найден до записи основного документа, и составное поле заполнится без ошибок.
Если объем переносимых данных велик (десятки тысяч заметок или документов), выполнение отдельного запроса для поиска каждого партнера сильно замедлит процесс загрузки. Рассмотрим альтернативный подход — кэширование.
Вы можете на этапе загрузки данных (в глобальных обработчиках) один раз сформировать соответствие «ИНН/КПП -> Ссылка на Партнера» и поместить его в глобальную переменную (например, в структуру параметров сеанса обмена). При поиске конкретного партнера в ПКО вы просто обращаетесь к этому кэшу. Это радикально снизит нагрузку на СУБД приемника и ускорит синхронизацию.
Комбинируя эти методы (указание типа через ИмяПКО, передачу данных через ВходящиеДанные и перехват алгоритма в обработчике «Поля поиска»), мы можем гибко и надежно получать Партнера из исходного Контрагента даже при выгрузке в составные реквизиты УТ 11.