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