Как выгрузить контактную информацию из табличной части справочника в регистр сведений в Конвертации данных 2.1?

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

При переносе данных между конфигурациями «1С:Предприятие» разработчики часто сталкиваются с несовпадением структур хранения данных. Классический пример такой задачи — перенос контактной информации (КИ). В старых или сильно кастомизированных конфигурациях-источниках (например, в некоторых редакциях «Управление нашей фирмой» или самописных решениях) контактная информация может храниться непосредственно в табличной части справочника (например, Контрагенты или ФизическиеЛица). В современных же типовых конфигурациях-приемниках («Комплексная автоматизация», «ERP Управление предприятием», «Бухгалтерия предприятия»), работающих на базе Библиотеки стандартных подсистем (БСП), эти данные хранятся в специализированном регистре сведений (КонтактнаяИнформация).

Решение этой задачи в «Конвертации данных 2.1» (КД 2.1) имеет ряд важных нюансов. Обычный интерактивный перенос через обработку «Универсальный обмен данными XML» настраивается относительно просто. Однако, если обмен выполняется регулярно в автоматическом режиме через планы обмена на базе БСП, стандартные подходы могут вызывать критические ошибки или полностью игнорироваться системой. В этой статье мы подробно разберем все способы реализации такого переноса, проанализируем причины сбоев и настроим наиболее стабильный и отказоустойчивый алгоритм.

Почему стандартный метод ВыгрузитьПоПравилу() дает сбой в обменах через БСП

Многие программисты пытаются решить задачу «в лоб»: написать запрос к табличной части справочника-источника и выгрузить строки с помощью функции ВыгрузитьПоПравилу(). При использовании интерактивной обработки выгрузки этот метод работает корректно. Но как только правила загружаются в типовой обмен БСП, система начинает выдавать ошибки структуры XML или транзакции загрузки. Выясним причину этого поведения:

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

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

Вариант 1. Использование ПВД с произвольным алгоритмом (для разового переноса данных)

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

Шаг 1. Настройка ПКО для регистра сведений. Создадим новое правило конвертации объектов (ПКО), например, с именем КонтактнаяИнформация:

Шаг 2. Создание ПВД с произвольным алгоритмом. Создадим новое ПВД, укажем для него способ выборки данных «Произвольный алгоритм» и свяжем его с созданным ранее ПКО КонтактнаяИнформация. В обработчике события Перед обработкой напишем следующий код выборки:


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

ВыборкаДанных = Запрос.Выполнить().Выбрать();

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

Вариант 2. Выборочная выгрузка через ВыгрузитьПоПравилу() в ПКО справочника

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

Проанализируем этот подход. Нам по-прежнему потребуется настроить ПКО КонтактнаяИнформация с пустым источником и флагами «Получить из входящих данных» в ПКС. Выгрузку будем инициировать в обработчике события После выгрузки в ПКО Контрагенты:


// Проверим, что выгружается элемент, а не группа справочника
Если Не Источник.ЭтоГруппа Тогда
    
    // Запрашиваем контактную информацию только для текущего выгружаемого объекта
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	КонтрагентыКИ.Ссылка КАК Объект,
        |	КонтрагентыКИ.Тип КАК Тип,
        |	КонтрагентыКИ.Вид КАК Вид,
        |	КонтрагентыКИ.Представление КАК Представление
        |ИЗ
        |	Справочник.Контрагенты.КонтактнаяИнформация КАК КонтрагентыКИ
        |ГДЕ
        |	КонтрагентыКИ.Ссылка = &Ссылка";
        
    Запрос.УстановитьПараметр("Ссылка", Источник.Ссылка);
    Выборка = Запрос.Выполнить().Выбрать();
    
    Пока Выборка.Следующий() Цикл
        // Формируем структуру входящих данных для передачи в ПКО регистра
        ВходящиеДанные = Новый Структура;
        ВходящиеДанные.Вставить("Объект", Выборка.Объект);
        ВходящиеДанные.Вставить("Тип", Выборка.Тип);
        ВходящиеДанные.Вставить("Вид", Выборка.Вид);
        ВходящиеДанные.Вставить("Представление", Выборка.Представление);
        
        // Выгружаем каждую строку по правилу конвертации
        ВыгрузитьПоПравилу(,, ВходящиеДанные,, "КонтактнаяИнформация");
    КонецЦикла;
    
КонецЕсли;

Этот метод решает проблему селективности (выгружаются только КИ участвующих в обмене контрагентов). Тем не менее, он сохраняет критический недостаток — невозможность очистить удаленную в источнике информацию на стороне приемника, а также потенциальные ошибки разбора XML-структур в БСП.

Вариант 3. Использование функции ВыгрузитьРегистр() — оптимальное решение для обменов БСП

Для обменов на базе планов обмена БСП наиболее надежным и архитектурно правильным решением является использование встроенной функции КД 2.1 ВыгрузитьРегистр(). Рассмотрим подробнее, как работает этот механизм.

Функция ВыгрузитьРегистр() формирует в выгружаемом файле правильную XML-структуру полноценного набора записей регистра сведений с установленным отбором по объекту-владельцу. При загрузке такого пакета на стороне приемника БСП выполняет транзакционную запись: сначала очищает все старые записи регистра по данному отбору (например, по конкретному контрагенту), а затем записывает новые актуальные строки. Это полностью решает проблему «фантомных» удаленных контактов и обеспечивает абсолютную ссылочную целостность данных.

Разберем по шагам реализацию данного механизма.

Шаг 1. Настройка ПКО для регистра сведений

Создайте или отредактируйте ПКО для регистра сведений (например, ПКО КонтактнаяИнформация):

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

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

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


Если Не Источник.ЭтоГруппа Тогда
    
    // 1. Формируем таблицу отбора для набора записей регистра
    ТаблицаОтбора = Новый ТаблицаЗначений;
    ТаблицаОтбора.Колонки.Добавить("Имя");
    ТаблицаОтбора.Колонки.Добавить("Значение");
    ТаблицаОтбора.Колонки.Добавить("Использование");
    
    НоваяСтрокаОтбора = ТаблицаОтбора.Добавить();
    НоваяСтрокаОтбора.Имя = "Объект"; // Имя измерения отбора в регистре-приемнике
    НоваяСтрокаОтбора.Значение = Источник.Ссылка;
    НоваяСтрокаОтбора.Использование = Истина;
    
    // 2. Формируем таблицу выгружаемых строк (данные из ТЧ справочника)
    ТаблицаСтрок = Новый ТаблицаЗначений;
    ТаблицаСтрок.Колонки.Добавить("Объект");
    ТаблицаСтрок.Колонки.Добавить("Тип");
    ТаблицаСтрок.Колонки.Добавить("Вид");
    ТаблицаСтрок.Колонки.Добавить("Представление");
    
    // В современных конфигурациях на БСП 3.x контактная информация часто хранится
    // в формате JSON/XML внутри поля "ЗначенияПолей". Добавим эту колонку при необходимости.
    ТаблицаСтрок.Колонки.Добавить("ЗначенияПолей"); 
    
    // Заполняем строки данными из табличной части источника
    Для Каждого СтрокаТЧ Из Источник.КонтактнаяИнформация Цикл
        НоваяСтрока = ТаблицаСтрок.Добавить();
        ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТЧ);
        НоваяСтрока.Объект = Источник.Ссылка; // Явно привязываем строку к контрагенту
    КонецЦикла;
    
    // 3. Упаковываем отбор и строки в структуру псевдо-набора записей
    НаборЗаписейДляВыгрузки = Новый Структура("Отбор, Строки");
    НаборЗаписейДляВыгрузки.Отбор = ТаблицаОтбора;
    НаборЗаписейДляВыгрузки.Строки = ТаблицаСтрок;
    
    // 4. Вызываем специализированную функцию выгрузки регистра сведений
    // Параметры: НаборЗаписей, ПравилоВыгрузки, Свойства, НеВыгружатьПоСсылкам, ИмяПКО
    ВыгрузитьРегистр(НаборЗаписейДляВыгрузки, , , Истина, "КонтактнаяИнформация");

КонецЕсли;

Анализ ключевых нюансов реализации

Проанализируем важные детали работы написанного алгоритма, которые гарантируют его стабильность в любых условиях эксплуатации обмена:

Применение описанного метода с использованием функции ВыгрузитьРегистр() гарантирует стабильную синхронизацию контактной информации без сбоев транзакций БСП и с полной поддержкой удаления неактуальных записей на стороне приемника.

← На главную