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