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