При переносе данных между конфигурациями «1С:Предприятие» разработчики регулярно сталкиваются со следующей проблемой: в старых конфигурациях (таких как Управление торговлей 10.3, Управление производственным предприятием 1.3, Комплексная автоматизация 1.1) контактная информация (КИ) хранится в независимом регистре сведений КонтактнаяИнформация. В современных же решениях (Управление торговлей 11, Бухгалтерия предприятия 3.0, ERP 2) КИ перенесена в табличные части справочников (например, ТЧ КонтактнаяИнформация справочника Контрагенты).
Когда мы настраиваем выборочный обмен (например, переносим только тех контрагентов, у которых есть определенная организация в договоре, или работаем в рамках узла плана обмена), стандартная выгрузка независимого регистра сведений «в лоб» не подходит. Если выгружать регистр КИ целиком, мы перенесем гигабайты лишней информации. Если не выгружать — контрагенты приедут без адресов и телефонов. Рассмотрим подробнее, как связать выгрузку справочника и независимого регистра сведений с помощью конфигурации «Конвертация данных 2.1» (КД 2.1).
Представим ситуацию, когда структура хранения КИ в источнике и приемнике совпадает (в обеих базах это независимый регистр сведений), но нам нужно передавать контактную информацию строго для тех контрагентов, которые зарегистрированы на узле плана обмена. Напрямую регистрировать записи регистра КИ в плане обмена — трудоемко и неэффективно. Гораздо проще выгружать их «прицепом» вместе с контрагентом.
Разберем по шагам, как это реализовать:
КонтактнаяИнформация. В качестве источника и приемника указываем регистр сведений РегистрСведенийЗапись.КонтактнаяИнформация.Контрагенты. Нам понадобится обработчик события «После выгрузки». Этот обработчик выполняется на стороне источника сразу после того, как сам контрагент успешно выгружен в XML.Источник), и программно отправляем их в файл обмена.Проанализируем пример кода для обработчика «После выгрузки» ПКО Контрагенты:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КИ.Объект КАК Объект,
| КИ.Тип КАК Тип,
| КИ.Вид КАК Вид,
| КИ.Представление КАК Представление,
| КИ.Поле1 КАК Поле1,
| КИ.Поле2 КАК Поле2,
| КИ.Поле3 КАК Поле3,
| КИ.Поле4 КАК Поле4,
| КИ.Поле5 КАК Поле5,
| КИ.Комментарий КАК Комментарий
|ИЗ
| РегистрСведений.КонтактнаяИнформация КАК КИ
|ГДЕ
| КИ.Объект = &Объект";
Запрос.УстановитьПараметр("Объект", Источник);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Создаем структуру свойств, которую передадим в ПКО регистра КИ
СвойстваЗаписи = Новый Структура;
СвойстваЗаписи.Вставить("Объект", Выборка.Объект);
СвойстваЗаписи.Вставить("Тип", Выборка.Тип);
СвойстваЗаписи.Вставить("Вид", Выборка.Вид);
СвойстваЗаписи.Вставить("Представление", Выборка.Представление);
СвойстваЗаписи.Вставить("Поле1", Выборка.Поле1);
СвойстваЗаписи.Вставить("Поле2", Выборка.Поле2);
СвойстваЗаписи.Вставить("Поле3", Выборка.Поле3);
СвойстваЗаписи.Вставить("Поле4", Выборка.Поле4);
СвойстваЗаписи.Вставить("Поле5", Выборка.Поле5);
СвойстваЗаписи.Вставить("Комментарий", Выборка.Комментарий);
// Программно вызываем выгрузку записи регистра сведений по ПКО "КонтактнаяИнформация"
ВыгрузитьПоПравилу(,, СвойстваЗаписи,, "КонтактнаяИнформация");
КонецЦикла;
Использование метода ВыгрузитьПоПравилу гарантирует, что в XML-файл выгрузки попадут только записи регистра, жестко связанные с выгружаемым в данный момент контрагентом. Никакой лишней информации в файл обмена записано не будет.
Если мы осуществляем переход со старой конфигурации на новую (например, УТ 10.3 -> БП 3.0), то в базе-приемнике КИ должна храниться внутри табличной части КонтактнаяИнформация справочника Контрагенты. В этом случае первый способ не подойдет, так как приемник ожидает данные КИ непосредственно в XML-структуре самого контрагента.
Для решения этой задачи в КД 2.1 существует мощный механизм — «Входящие данные» (коллекции объектов).
Выясним алгоритм настройки правил:
Контрагенты создаем группу свойств (ПКГС) для табличной части КонтактнаяИнформация. Источник оставляем пустым, а в качестве приемника выбираем табличную часть КонтактнаяИнформация.Контрагенты в обработчике «Перед выгрузкой» пишем код, который соберет данные из регистра КИ источника, упакует их в таблицу значений и передаст ее во входящие данные.Рассмотрим пример кода для обработчика «Перед выгрузкой» ПКО Контрагенты:
// 1. Инициализируем таблицу значений со структурой, аналогичной ТЧ КонтактнаяИнформация в приемнике
ТаблицаКИ = Новый ТаблицаЗначений;
ТаблицаКИ.Колонки.Добавить("Тип");
ТаблицаКИ.Колонки.Добавить("Вид");
ТаблицаКИ.Колонки.Добавить("Представление");
ТаблицаКИ.Колонки.Добавить("ЗначенияПолей"); // Служебное поле БСП
// 2. Выбираем КИ текущего контрагента из регистра сведений источника
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КИ.Тип КАК Тип,
| КИ.Вид КАК Вид,
| КИ.Представление КАК Представление
|ИЗ
| РегистрСведений.КонтактнаяИнформация КАК КИ
|ГДЕ
| КИ.Объект = &Объект";
Запрос.УстановитьПараметр("Объект", Источник);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
НоваяСтрока = ТаблицаКИ.Добавить();
НоваяСтрока.Тип = Выборка.Тип;
// Внимание! Виды контактной информации в источнике и приемнике могут отличаться.
// Если предопределенные элементы разные, здесь необходимо написать алгоритм сопоставления.
НоваяСтрока.Вид = Выборка.Вид;
НоваяСтрока.Представление = Выборка.Представление;
НоваяСтрока.ЗначенияПолей = ""; // Пока оставляем пустым, заполним далее
КонецЦикла;
// 3. Передаем подготовленную таблицу во ВходящиеДанные под именем табличной части приемника
Если ТаблицаКИ.Количество() > 0 Тогда
ВходящиеДанные = Новый Структура;
ВходящиеДанные.Вставить("КонтактнаяИнформация", ТаблицаКИ);
КонецЕсли;
При выгрузке КД 2.1 автоматически сопоставит переданную во ВходящиеДанные таблицу значений с табличной частью контрагента в приемнике и запишет данные в XML-файл так, как будто они изначально хранились в табличной части источника.
Часто после переноса КИ во входящие данные разработчики сталкиваются с неприятным сюрпризом: данные успешно записались в табличную часть контрагента в базе-приемнике, но при открытии карточки в режиме «1С:Предприятие» поля адресов и телефонов отображаются пустыми.
Это происходит потому, что современные конфигурации на базе БСП (Библиотеки стандартных подсистем) используют сложную структуру хранения КИ. Помимо простого текстового поля Представление, в табличной части КИ есть служебное поле ЗначенияПолей. В нем хранится сериализованная структура адреса или телефона (в формате XML или JSON) с разбивкой по полям (индекс, город, улица, дом и т.д.). Без заполнения поля ЗначенияПолей форма элемента БСП просто не "видит" адрес.
Чтобы решить эту проблему наиболее надежным способом, задействуем обработчик на стороне приемника. В ПКО Контрагенты перейдем в обработчик события «После загрузки» и вызовем стандартные процедуры БСП для генерации детальной информации по текстовому представлению.
Рассмотрим пример кода в обработчике «После загрузки» ПКО Контрагенты на стороне приемника:
// Обходим строки загруженной табличной части КИ контрагента
Для Каждого СтрокаКИ Из Объект.КонтактнаяИнформация Цикл
// Если представление заполнено, а детальные значения полей отсутствуют
Если НЕ ПустаяСтрока(СтрокаКИ.Представление) И ПустаяСтрока(СтрокаКИ.ЗначенияПолей) Тогда
Попытка
// Используем программный интерфейс БСП для разбора представления в XML/JSON структуру КИ
СтрокаКИ.ЗначенияПолей = УправлениеКонтактнойИнформациейСлужебный.СформироватьЗначенияПолейИзПредставления(
СтрокаКИ.Представление,
СтрокаКИ.Тип,
СтрокаКИ.Вид
);
Исключение
// На случай, если в текущей версии БСП имя метода или параметры отличаются
ЗаписьЖурналаРегистрации("ПереносДанных.КонтактнаяИнформация",
УровеньЖурналаРегистрации.Предупреждение,,,
"Не удалось детализировать КИ для объекта: " + Строка(Объект) + ". Ошибка: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
Этот простой шаг гарантирует, что перенесенные адреса и телефоны будут корректно распознаны БСП, отобразятся во всех формах карточек контрагентов и станут доступны для регламентированной отчетности и автозаполнения документов.