Как в КД 2.1 настроить выгрузку номенклатуры с объединением группы, наименования и характеристики?

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

При настройке интеграции между старыми и новыми конфигурациями 1С (например, при переносе данных из «Управление торговлей, ред. 10.3» в «Бухгалтерию предприятия, ред. 3.0») разработчики часто сталкиваются с различиями в архитектуре учета. Одно из наиболее частых несовпадений — использование характеристик. В торговой базе учет товаров может вестись в разрезе характеристик, тогда как в бухгалтерии они не требуются, но уникальные сочетания должны стать отдельными позициями номенклатуры.

В этой статье мы подробно разберем, как в программе «1С:Конвертация данных 2.1» (КД 2.1) реализовать выгрузку номенклатуры, формируя её наименование по шаблону: «Группа товара» + «Номенклатура» + «Характеристика». Также мы настроим корректный поиск по наименованию в базе-приемнике и научимся передавать дополнительные реквизиты из табличной части документа.

---

Шаг 1. Безопасное формирование наименования номенклатуры

Первое, с чего стоит начать — это создание Правила Конвертации Объектов (ПКО) для номенклатуры. В качестве источника в данном ПКО мы укажем справочник ХарактеристикиНоменклатуры, а в качестве приемника — справочник Номенклатура.

Простая конкатенация строк вида Источник.Владелец.Родитель.Наименование, предложенная на многих форумах, является опасной практикой. Если у товара в базе-источнике не заполнена родительская группа (товар лежит в корне справочника) или у характеристики не определен владелец, система аварийно завершит работу с ошибкой «Поле объекта не обнаружено».

Давайте рассмотрим правильный, безопасный вариант написания кода в обработчике «Перед выгрузкой» Правила Конвертации Свойств (ПКС) для реквизита Наименование:


РодительНаименование = "";
Если ЗначениеЗаполнено(Источник.Владелец) И ЗначениеЗаполнено(Источник.Владелец.Родитель) Тогда
    РодительНаименование = Источник.Владелец.Родитель.Наименование + " ";
КонецЕсли;

ВладелецНаименование = "";
Если ЗначениеЗаполнено(Источник.Владелец) Тогда
    ВладелецНаименование = Источник.Владелец.Наименование;
КонецЕсли;

ХарактеристикаНаименование = ?(ЗначениеЗаполнено(Источник.Наименование), " " + Источник.Наименование, "");

// СокрЛП уберет лишние пробелы по краям, если группа или характеристика отсутствуют
Значение = СокрЛП(РодительНаименование + ВладелецНаименование + ХарактеристикаНаименование);

Этот код гарантирует стабильность выгрузки при любых сценариях заполнения данных в исходной базе данных.

---

Шаг 2. Настройка поиска по наименованию при загрузке

Поскольку мы создаем виртуальную номенклатуру, объединяя физический товар и его характеристику, у создаваемого объекта в базе-приемнике не будет прямого соответствия по уникальному идентификатору (GUID). Следовательно, сопоставление должно происходить исключительно по полям поиска.

Для реализации этой логики выполним следующие настройки в КД 2.1:

  1. Откроем ПКО, отвечающее за создание номенклатуры.
  2. Перейдем на вкладку «Настройки» и установим флаг «Продолжить поиск по полям поиска, если по идентификатору объект приемник не найден». Это критически важно: без этого флага система попытается сопоставить объект по GUID источника (который принадлежит характеристике) и может перезаписать или задвоить данные.
  3. В списке ПКС найдем свойство Наименование и установим для него галочку в колонке «Поиск».
  4. Если требуется выполнять поиск без учета регистра или со специальной очисткой символов, мы можем дополнительно прописать алгоритм в обработчике «Поля поиска» на уровне ПКО.

---

Шаг 3. Передача дополнительных данных из табличной части документа

Зачастую бизнес-логика требует передать в карточку создаваемой номенклатуры дополнительные свойства, которых нет ни в справочнике номенклатуры, ни в характеристиках, но которые присутствуют в строке табличной части документа «Счет на оплату» (например, «Размер», «Спецификация» или «Комментарий»).

Проанализируем два профессиональных подхода к решению этой задачи.

Вариант А. Механизм Входящих и Исходящих данных (Рекомендуемый подход)

Этот способ является наиболее чистым и поддерживаемым, поскольку он не нарушает стандартный жизненный цикл объектов КД.

Пошаговый алгоритм настройки выглядит так:

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

ИсходящиеДанные = Новый Структура;
ИсходящиеДанные.Вставить("Размер", ОбъектКоллекции.Размер); 
// Можно также выполнить запрос для получения других свойств характеристики:
ИсходящиеДанные.Вставить("ДополнительноеСвойство", ПолучитьСвойствоИзЗапроса(ОбъектКоллекции.Характеристика));
  1. В ПКО Номенклатуры создаем ПКС для нужных свойств приемника (например, для свойства Размер в БП 3.0).
  2. Для этих ПКС в настройках обязательно взводим флаг «Получить из входящих данных». При импорте КД автоматически свяжет структуру ИсходящиеДанные со структурой ВходящиеДанные правила конвертации номенклатуры, и реквизиты будут успешно заполнены.

Вариант Б. Использование Структуры в качестве Источника

Если структура метаданных настолько сложна, что стандартное ПКО не справляется, мы можем передать в обработку полностью собранный вручную объект.

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

СтруктураНоменклатуры = Новый Структура;
СтруктураНоменклатуры.Вставить("Наименование", СформированноеНаименование);
СтруктураНоменклатуры.Вставить("Размер", ОбъектКоллекции.Размер);
СтруктураНоменклатуры.Вставить("СтавкаНДС", ОбъектКоллекции.Номенклатура.СтавкаНДС);

Значение = СтруктураНоменклатуры;
ИмяПКО = "НоменклатураБезИсточника"; // Указываем имя нашего ПКО

---

Шаг 4. Оптимизация производительности с помощью кэширования

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

Выясним, как развернуть глобальный кэш соответствий в рамках сессии обмена:

  1. В обработчике конвертации «Перед выгрузкой данных» инициализируем таблицу или соответствие для кэша:

Параметры.Вставить("КэшНоменклатуры", Новый Соответствие);

  1. В ПКС номенклатуры перед началом ресурсоемких вычислений наименования проверяем, нет ли уже готового значения в кэше:

КлючКэша = Строка(Источник.Владелец.УникальныйИдентификатор()) + "_" + Строка(Источник.УникальныйИдентификатор());
НайденноеЗначение = Параметры.КэшНоменклатуры.Получить(КлючКэша);

Если НайденноеЗначение <> Неопределено Тогда
    Значение = НайденноеЗначение;
Иначе
    // Выполняем расчет наименования, как описано в Шаге 1
    // ...
    // И записываем результат в кэш:
    Параметры.КэшНоменклатуры.Вставить(КлючКэша, Значение);
КонецЕсли;

Этот несложный прием позволяет сократить время выгрузки документов в несколько раз, сводя к минимуму обращения к базе данных и снижая нагрузку на сервер 1С.

← На главную