При настройке интеграции между старыми и новыми конфигурациями 1С (например, при переносе данных из «Управление торговлей, ред. 10.3» в «Бухгалтерию предприятия, ред. 3.0») разработчики часто сталкиваются с различиями в архитектуре учета. Одно из наиболее частых несовпадений — использование характеристик. В торговой базе учет товаров может вестись в разрезе характеристик, тогда как в бухгалтерии они не требуются, но уникальные сочетания должны стать отдельными позициями номенклатуры.
В этой статье мы подробно разберем, как в программе «1С:Конвертация данных 2.1» (КД 2.1) реализовать выгрузку номенклатуры, формируя её наименование по шаблону: «Группа товара» + «Номенклатура» + «Характеристика». Также мы настроим корректный поиск по наименованию в базе-приемнике и научимся передавать дополнительные реквизиты из табличной части документа.
---
Первое, с чего стоит начать — это создание Правила Конвертации Объектов (ПКО) для номенклатуры. В качестве источника в данном ПКО мы укажем справочник ХарактеристикиНоменклатуры, а в качестве приемника — справочник Номенклатура.
Простая конкатенация строк вида Источник.Владелец.Родитель.Наименование, предложенная на многих форумах, является опасной практикой. Если у товара в базе-источнике не заполнена родительская группа (товар лежит в корне справочника) или у характеристики не определен владелец, система аварийно завершит работу с ошибкой «Поле объекта не обнаружено».
Давайте рассмотрим правильный, безопасный вариант написания кода в обработчике «Перед выгрузкой» Правила Конвертации Свойств (ПКС) для реквизита Наименование:
РодительНаименование = "";
Если ЗначениеЗаполнено(Источник.Владелец) И ЗначениеЗаполнено(Источник.Владелец.Родитель) Тогда
РодительНаименование = Источник.Владелец.Родитель.Наименование + " ";
КонецЕсли;
ВладелецНаименование = "";
Если ЗначениеЗаполнено(Источник.Владелец) Тогда
ВладелецНаименование = Источник.Владелец.Наименование;
КонецЕсли;
ХарактеристикаНаименование = ?(ЗначениеЗаполнено(Источник.Наименование), " " + Источник.Наименование, "");
// СокрЛП уберет лишние пробелы по краям, если группа или характеристика отсутствуют
Значение = СокрЛП(РодительНаименование + ВладелецНаименование + ХарактеристикаНаименование);
Этот код гарантирует стабильность выгрузки при любых сценариях заполнения данных в исходной базе данных.
---
Поскольку мы создаем виртуальную номенклатуру, объединяя физический товар и его характеристику, у создаваемого объекта в базе-приемнике не будет прямого соответствия по уникальному идентификатору (GUID). Следовательно, сопоставление должно происходить исключительно по полям поиска.
Для реализации этой логики выполним следующие настройки в КД 2.1:
Наименование и установим для него галочку в колонке «Поиск».---
Зачастую бизнес-логика требует передать в карточку создаваемой номенклатуры дополнительные свойства, которых нет ни в справочнике номенклатуры, ни в характеристиках, но которые присутствуют в строке табличной части документа «Счет на оплату» (например, «Размер», «Спецификация» или «Комментарий»).
Проанализируем два профессиональных подхода к решению этой задачи.
Этот способ является наиболее чистым и поддерживаемым, поскольку он не нарушает стандартный жизненный цикл объектов КД.
Пошаговый алгоритм настройки выглядит так:
ИсходящиеДанные:
ИсходящиеДанные = Новый Структура;
ИсходящиеДанные.Вставить("Размер", ОбъектКоллекции.Размер);
// Можно также выполнить запрос для получения других свойств характеристики:
ИсходящиеДанные.Вставить("ДополнительноеСвойство", ПолучитьСвойствоИзЗапроса(ОбъектКоллекции.Характеристика));
Размер в БП 3.0).ИсходящиеДанные со структурой ВходящиеДанные правила конвертации номенклатуры, и реквизиты будут успешно заполнены.Если структура метаданных настолько сложна, что стандартное ПКО не справляется, мы можем передать в обработку полностью собранный вручную объект.
СтруктураНоменклатуры = Новый Структура;
СтруктураНоменклатуры.Вставить("Наименование", СформированноеНаименование);
СтруктураНоменклатуры.Вставить("Размер", ОбъектКоллекции.Размер);
СтруктураНоменклатуры.Вставить("СтавкаНДС", ОбъектКоллекции.Номенклатура.СтавкаНДС);
Значение = СтруктураНоменклатуры;
ИмяПКО = "НоменклатураБезИсточника"; // Указываем имя нашего ПКО
---
При выгрузке больших документов, содержащих сотни строк, динамическое формирование строк и выполнение запросов для каждого товара могут критически замедлить процесс выгрузки. Чтобы избежать многократного выполнения одного и того же кода для дублирующихся позиций, настроим кэширование.
Выясним, как развернуть глобальный кэш соответствий в рамках сессии обмена:
Параметры.Вставить("КэшНоменклатуры", Новый Соответствие);
КлючКэша = Строка(Источник.Владелец.УникальныйИдентификатор()) + "_" + Строка(Источник.УникальныйИдентификатор());
НайденноеЗначение = Параметры.КэшНоменклатуры.Получить(КлючКэша);
Если НайденноеЗначение <> Неопределено Тогда
Значение = НайденноеЗначение;
Иначе
// Выполняем расчет наименования, как описано в Шаге 1
// ...
// И записываем результат в кэш:
Параметры.КэшНоменклатуры.Вставить(КлючКэша, Значение);
КонецЕсли;
Этот несложный прием позволяет сократить время выгрузки документов в несколько раз, сводя к минимуму обращения к базе данных и снижая нагрузку на сервер 1С.