Как перенести контактную информацию контрагентов при выгрузке по плану обмена в 1С:Конвертация данных 2.1?

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

При переносе данных между конфигурациями «1С:Предприятие» разработчики регулярно сталкиваются со следующей проблемой: в старых конфигурациях (таких как Управление торговлей 10.3, Управление производственным предприятием 1.3, Комплексная автоматизация 1.1) контактная информация (КИ) хранится в независимом регистре сведений КонтактнаяИнформация. В современных же решениях (Управление торговлей 11, Бухгалтерия предприятия 3.0, ERP 2) КИ перенесена в табличные части справочников (например, ТЧ КонтактнаяИнформация справочника Контрагенты).

Когда мы настраиваем выборочный обмен (например, переносим только тех контрагентов, у которых есть определенная организация в договоре, или работаем в рамках узла плана обмена), стандартная выгрузка независимого регистра сведений «в лоб» не подходит. Если выгружать регистр КИ целиком, мы перенесем гигабайты лишней информации. Если не выгружать — контрагенты приедут без адресов и телефонов. Рассмотрим подробнее, как связать выгрузку справочника и независимого регистра сведений с помощью конфигурации «Конвертация данных 2.1» (КД 2.1).

Решение 1: Выгрузка связанных записей регистра сведений через обработчик «После выгрузки» (для идентичных структур)

Представим ситуацию, когда структура хранения КИ в источнике и приемнике совпадает (в обеих базах это независимый регистр сведений), но нам нужно передавать контактную информацию строго для тех контрагентов, которые зарегистрированы на узле плана обмена. Напрямую регистрировать записи регистра КИ в плане обмена — трудоемко и неэффективно. Гораздо проще выгружать их «прицепом» вместе с контрагентом.

Разберем по шагам, как это реализовать:

  1. Создаем стандартное ПКО (Правило конвертации объектов) для регистра сведений. Назовем его, например, КонтактнаяИнформация. В качестве источника и приемника указываем регистр сведений РегистрСведенийЗапись.КонтактнаяИнформация.
  2. Переходим в ПКО справочника Контрагенты. Нам понадобится обработчик события «После выгрузки». Этот обработчик выполняется на стороне источника сразу после того, как сам контрагент успешно выгружен в XML.
  3. В обработчике «После выгрузки» пишем запрос, который выбирает из базы данных источника только те записи КИ, которые принадлежат текущему выгружаемому контрагенту (переменная Источник), и программно отправляем их в файл обмена.

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


Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|	КИ.Объект КАК Объект,
|	КИ.Тип КАК Тип,
|	КИ.Вид КАК Вид,
|	КИ.Представление КАК Представление,
|	КИ.Поле1 КАК Поле1,
|	КИ.Поле2 КАК Поле2,
|	КИ.Поле3 КАК Поле3,
|	КИ.Поле4 КАК Поле4,
|	КИ.Поле5 КАК Поле5,
|	КИ.Комментарий КАК Комментарий
|ИЗ
|	РегистрСведений.КонтактнаяИнформация КАК КИ
|ГДЕ
|	КИ.Объект = &Объект";

Запрос.УстановитьПараметр("Объект", Источник);
Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл
    // Создаем структуру свойств, которую передадим в ПКО регистра КИ
    СвойстваЗаписи = Новый Структура;
    СвойстваЗаписи.Вставить("Объект", Выборка.Объект);
    СвойстваЗаписи.Вставить("Тип", Выборка.Тип);
    СвойстваЗаписи.Вставить("Вид", Выборка.Вид);
    СвойстваЗаписи.Вставить("Представление", Выборка.Представление);
    СвойстваЗаписи.Вставить("Поле1", Выборка.Поле1);
    СвойстваЗаписи.Вставить("Поле2", Выборка.Поле2);
    СвойстваЗаписи.Вставить("Поле3", Выборка.Поле3);
    СвойстваЗаписи.Вставить("Поле4", Выборка.Поле4);
    СвойстваЗаписи.Вставить("Поле5", Выборка.Поле5);
    СвойстваЗаписи.Вставить("Комментарий", Выборка.Комментарий);

    // Программно вызываем выгрузку записи регистра сведений по ПКО "КонтактнаяИнформация"
    ВыгрузитьПоПравилу(,, СвойстваЗаписи,, "КонтактнаяИнформация");
КонецЦикла;

Использование метода ВыгрузитьПоПравилу гарантирует, что в XML-файл выгрузки попадут только записи регистра, жестко связанные с выгружаемым в данный момент контрагентом. Никакой лишней информации в файл обмена записано не будет.

Решение 2: Перенос из независимого регистра в табличную часть приемника через «Входящие данные»

Если мы осуществляем переход со старой конфигурации на новую (например, УТ 10.3 -> БП 3.0), то в базе-приемнике КИ должна храниться внутри табличной части КонтактнаяИнформация справочника Контрагенты. В этом случае первый способ не подойдет, так как приемник ожидает данные КИ непосредственно в XML-структуре самого контрагента.

Для решения этой задачи в КД 2.1 существует мощный механизм — «Входящие данные» (коллекции объектов).

Выясним алгоритм настройки правил:

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

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


// 1. Инициализируем таблицу значений со структурой, аналогичной ТЧ КонтактнаяИнформация в приемнике
ТаблицаКИ = Новый ТаблицаЗначений;
ТаблицаКИ.Колонки.Добавить("Тип");
ТаблицаКИ.Колонки.Добавить("Вид");
ТаблицаКИ.Колонки.Добавить("Представление");
ТаблицаКИ.Колонки.Добавить("ЗначенияПолей"); // Служебное поле БСП

// 2. Выбираем КИ текущего контрагента из регистра сведений источника
Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|	КИ.Тип КАК Тип,
|	КИ.Вид КАК Вид,
|	КИ.Представление КАК Представление
|ИЗ
|	РегистрСведений.КонтактнаяИнформация КАК КИ
|ГДЕ
|	КИ.Объект = &Объект";

Запрос.УстановитьПараметр("Объект", Источник);
Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл
    НоваяСтрока = ТаблицаКИ.Добавить();
    НоваяСтрока.Тип = Выборка.Тип;
    
    // Внимание! Виды контактной информации в источнике и приемнике могут отличаться.
    // Если предопределенные элементы разные, здесь необходимо написать алгоритм сопоставления.
    НоваяСтрока.Вид = Выборка.Вид; 
    НоваяСтрока.Представление = Выборка.Представление;
    НоваяСтрока.ЗначенияПолей = ""; // Пока оставляем пустым, заполним далее
КонецЦикла;

// 3. Передаем подготовленную таблицу во ВходящиеДанные под именем табличной части приемника
Если ТаблицаКИ.Количество() > 0 Тогда
    ВходящиеДанные = Новый Структура;
    ВходящиеДанные.Вставить("КонтактнаяИнформация", ТаблицаКИ);
КонецЕсли;

При выгрузке КД 2.1 автоматически сопоставит переданную во ВходящиеДанные таблицу значений с табличной частью контрагента в приемнике и запишет данные в XML-файл так, как будто они изначально хранились в табличной части источника.

Важный подводный камень современных конфигураций: Формат БСП и поле «ЗначенияПолей»

Часто после переноса КИ во входящие данные разработчики сталкиваются с неприятным сюрпризом: данные успешно записались в табличную часть контрагента в базе-приемнике, но при открытии карточки в режиме «1С:Предприятие» поля адресов и телефонов отображаются пустыми.

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

Чтобы решить эту проблему наиболее надежным способом, задействуем обработчик на стороне приемника. В ПКО Контрагенты перейдем в обработчик события «После загрузки» и вызовем стандартные процедуры БСП для генерации детальной информации по текстовому представлению.

Рассмотрим пример кода в обработчике «После загрузки» ПКО Контрагенты на стороне приемника:


// Обходим строки загруженной табличной части КИ контрагента
Для Каждого СтрокаКИ Из Объект.КонтактнаяИнформация Цикл
    
    // Если представление заполнено, а детальные значения полей отсутствуют
    Если НЕ ПустаяСтрока(СтрокаКИ.Представление) И ПустаяСтрока(СтрокаКИ.ЗначенияПолей) Тогда
        
        Попытка
            // Используем программный интерфейс БСП для разбора представления в XML/JSON структуру КИ
            СтрокаКИ.ЗначенияПолей = УправлениеКонтактнойИнформациейСлужебный.СформироватьЗначенияПолейИзПредставления(
                СтрокаКИ.Представление, 
                СтрокаКИ.Тип, 
                СтрокаКИ.Вид
            );
        Исключение
            // На случай, если в текущей версии БСП имя метода или параметры отличаются
            ЗаписьЖурналаРегистрации("ПереносДанных.КонтактнаяИнформация",
                УровеньЖурналаРегистрации.Предупреждение,,,
                "Не удалось детализировать КИ для объекта: " + Строка(Объект) + ". Ошибка: " + ОписаниеОшибки());
        КонецПопытки;
        
    КонецЕсли;
    
КонецЦикла;

Этот простой шаг гарантирует, что перенесенные адреса и телефоны будут корректно распознаны БСП, отобразятся во всех формах карточек контрагентов и станут доступны для регламентированной отчетности и автозаполнения документов.

← На главную