При настройке обмена данными между конфигурациями «Управление торговлей, ред. 11» (УТ 11) и «Управление торговлей, ред. 10.3» (УТ 10) разработчики часто сталкиваются с архитектурными различиями систем. Одной из наиболее ярких проблем является разница в механизме работы характеристик номенклатуры.
В УТ 11 владельцем характеристики справочника ХарактеристикиНоменклатуры может выступать как конкретная Номенклатура, так и целый Вид номенклатуры (когда одна характеристика «Размер: XL» или «Цвет: Синий» является общей для всех товаров этого вида). В то же время в УТ 10 архитектура более строгая: владельцем характеристики может быть только конкретная номенклатурная позиция.
Если выполнять выгрузку стандартным образом (сопоставляя объекты по уникальному идентификатору GUID), мы неизбежно столкнемся с критическими ошибками загрузки (например, «Артикул не найден» или некорректная перезапись владельцев). Ведь одна и та же характеристика в источнике должна сопоставляться с абсолютно разными характеристиками разных товаров в приемнике.
В этой статье мы подробно разберем, как решить эту проблему в 1С:Конвертация данных 2.1 (КД 2). Мы рассмотрим два эффективных практических метода решения этой задачи.
Суть этого метода заключается в том, что мы заставляем систему принудительно «размножить» одну общую характеристику вида номенклатуры из источника на несколько индивидуальных характеристик для каждой конкретной номенклатуры в приемнике. Для этого нам потребуется связать контекст выгрузки документа с правилом конвертации самой характеристики.
Рассмотрим пошагово, как настроить правила конвертации свойств (ПКС) и объектов (ПКО).
Шаг 1. Передача контекста номенклатуры из документа-источника
В ПКО вашего документа (например, ЧекККМ или РеализацияТоваровУслуг) найдите табличную часть Товары и перейдите в ПКС Характеристика. Нам необходимо принудительно передать текущую номенклатуру строки табличной части в качестве будущего владельца характеристики. Для этого откроем обработчик «Перед выгрузкой» этого ПКС и пропишем следующий код:
// Формируем структуру исходящих данных для передачи в ПКО характеристики
ИсходящиеДанные = Новый Структура("Владелец");
ИсходящиеДанные.Владелец = ОбъектКоллекции.Номенклатура;
Шаг 2. Разделение объектов при выгрузке через КлючВыгружаемыхДанных
Если мы оставим всё как есть, то при выгрузке по ссылке механизм КД 2.1 выгрузит общую характеристику только один раз. В итоге в приемнике она запишется лишь для первого попавшегося товара. Чтобы этого избежать, нам нужно уникализировать выгрузку характеристики для каждого отдельного товара.
Перейдите в ПКО ХарактеристикиНоменклатуры. В обработчике события «Перед выгрузкой» этого ПКО переопределите стандартный ключ выгружаемых данных:
Если ТипЗнч(ВходящиеДанные) = Тип("Структура") И ВходящиеДанные.Свойство("Владелец") Тогда
// Формируем уникальный ключ на стыке ГУИД характеристики-источника и ГУИД конкретного товара
КлючВыгружаемыхДанных = Строка(Источник.Ссылка.УникальныйИдентификатор()) + "_" + Строка(ВходящиеДанные.Владелец.УникальныйИдентификатор());
КонецЕсли;
Благодаря этому коду Конвертация данных поймет, что перед ней разные сущности, и выгрузит в файл XML несколько экземпляров одной и той же характеристики с разными ключами.
Шаг 3. Настройка заполнения владельца характеристики в ПКО
В ПКО ХарактеристикиНоменклатуры найдите правило конвертации свойства Владелец. Чтобы оно корректно принимало переданную нами номенклатуру, выполните следующие настройки:
Владелец.ИсходящиеДанные (которая в ПКО приемника автоматически превращается во ВходящиеДанные).Шаг 4. Настройка правил поиска в приемнике
Так как мы искусственно разделяем общие характеристики на индивидуальные, сопоставление по стандартному ГУИД в приемнике работать не должно (иначе они будут затирать друг друга). Нам необходимо настроить поиск характеристик по сочетанию Владелец + Наименование.
Для этого в ПКО ХарактеристикиНоменклатуры перейдите в обработчик события «Поля поиска» и напишите следующий алгоритм:
Если СвойстваПоиска.Свойство("Владелец") И СвойстваПоиска.Свойство("Наименование") Тогда
// Отключаем стандартный поиск по уникальному идентификатору (GUID)
// и заставляем систему искать по установленным свойствам поиска
ПрекратитьПоиск = Ложь;
КонецЕсли;
При такой настройке при загрузке документа в УТ 10 система будет искать характеристику с конкретным наименованием именно у того товара, который указан в текущей строке документа. Если характеристика не найдена — создастся новая, привязанная к этой номенклатуре.
Если структура ваших правил обмена очень сложная, содержит много условных переходов, или вы не хотите перегружать ПКО характеристик сложной логикой входящих/исходящих данных, можно переложить задачу сопоставления на базу-приемник. В этом случае мы передаем характеристику в виде строки (наименования), а в базе УТ 10 программно ищем или создаем элемент справочника.
Шаг 1. Передача наименования характеристики текстом
В правилах конвертации свойств табличной части документа (например, ЧекККМ) для свойства Характеристика отключите стандартное правило конвертации (ПКО). Нам не нужно выгружать характеристику как объект-ссылку. Вместо этого мы передадим ее наименование:
ИмяХарактеристики).
Значение = "";
Если ЗначениеЗаполнено(ОбъектКоллекции.Характеристика) Тогда
Значение = ОбъектКоллекции.Характеристика.Наименование;
КонецЕсли;
Шаг 2. Поиск и создание характеристик «на лету» при загрузке в УТ 10
Теперь вся магия будет происходить на стороне приемника в момент записи загруженного документа. Перейдите в ПКО вашего документа и откройте обработчик события «После загрузки». Напишем код, который обойдет строки табличной части, найдет нужные характеристики по имени и владельцу, а в случае отсутствия — создаст их:
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
// Получаем наименование характеристики из временного параметра или реквизита строки
ИмяХарактеристики = СтрокаТЧ.ХарактеристикаНоменклатуры; // В зависимости от настроек ПКС
Если ЗначениеЗаполнено(ИмяХарактеристики) И ЗначениеЗаполнено(СтрокаТЧ.Номенклатура) Тогда
// Пытаемся найти существующую индивидуальную характеристику для данного товара
НайденнаяХарактеристика = Справочники.ХарактеристикиНоменклатуры.НайтиПоНаименованию(
ИмяХарактеристики,
Истина, ,
СтрокаТЧ.Номенклатура
);
Если НайденнаяХарактеристика.Пустая() Тогда
// Если характеристика не найдена, создаем новый элемент справочника в УТ 10
НоваяХар = Справочники.ХарактеристикиНоменклатуры.CreateItem();
НоваяХар.Владелец = СтрокаТЧ.Номенклатура;
НоваяХар.Наименование = ИмяХарактеристики;
Попытка
НоваяХар.Write();
СтрокаТЧ.ХарактеристикаНоменклатуры = НоваяХар.Ref;
Исключение
ЗаписьЖурналаРегистрации("ОбменДанными", УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка создания характеристики: " + ОписаниеОшибки());
КонецПопытки;
Иначе
// Если нашли — просто подставляем ссылку в строку документа
СтрокаТЧ.ХарактеристикаНоменклатуры = НайденнаяХарактеристика;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Этот метод гарантирует, что в базе-приемнике УТ 10 не появится «битых» ссылок на несуществующие характеристики, а все созданные элементы будут четко привязаны к своим товарам-владельцам.
Мы рассмотрели два различных подхода к решению проблемы сопоставления по владельцу в КД 2.1:
Выберите наиболее подходящий для вашего проекта вариант и используйте его для построения надежного и отказоустойчивого обмена данными!