Как в Конвертации данных 2.0 выгрузить независимый регистр сведений ШтрихкодыНоменклатуры вместе с документом реализации?

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

При настройке правил обмена в конфигурации «Конвертация данных 2.0» часто возникает задача оптимизации объема передаваемых данных. Для справочника Номенклатура обычно настраивают режим выгрузки данных «Выгружать при необходимости», чтобы переносить только те позиции, которые непосредственно фигурируют в выгружаемом документе реализации (РТУ). Однако независимый регистр сведений ШтрихкодыНоменклатуры не связан с документом напрямую и не участвует в стандартной выборке объектов, из-за чего штрихкоды для переносимых позиций остаются в исходной базе. Разберем, как корректно выгрузить записи регистра вместе с документом, проанализируем поведение обработчиков событий и рассмотрим варианты оптимизации выгрузки.

Выясним причину проблемы с обработчиками событий

При попытке разместить код выгрузки штрихкодов в обработчиках событий правила конвертации объекта (ПКО) Номенклатура разработчики нередко сталкиваются с тем, что код не выполняется. Проанализируем, почему это происходит:

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

Вариант 1. Выгрузка штрихкодов из обработчика документа реализации

Рабочим и надежным решением является программная выгрузка штрихкодов непосредственно из документа в обработчике «ПослеВыгрузки» ПКО РеализацияТоваровУслуг. Однако прямой перебор строк табличной части и выполнение запроса к регистру на каждой итерации цикла создают существенную нагрузку на СУБД (проблема «запрос в цикле»).

Оптимизируем этот процесс: соберем массив уникальных ссылок на номенклатуру из документа, выполним один пакетный запрос к регистру сведений ШтрихкодыНоменклатуры и передадим найденные записи в функцию ВыгрузитьПоПравилу().

Рассмотрим пример кода в обработчике «ПослеВыгрузки» ПКО документа:


// Получаем уникальный массив номенклатуры из табличной части документа
ТаблицаТовары = Источник.Товары.Выгрузить();
ТаблицаТовары.Свернуть("Номенклатура");
МассивНоменклатуры = ТаблицаТовары.ВыгрузитьКолонку("Номенклатура");

Если МассивНоменклатуры.Количество() > 0 Тогда
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   Штрихкоды.Штрихкод КАК Штрихкод,
        |   Штрихкоды.Номенклатура КАК Номенклатура,
        |   Штрихкоды.Характеристика КАК Характеристика,
        |   Штрихкоды.Упаковка КАК Упаковка
        |ИЗ
        |   РегистрСведений.ШтрихкодыНоменклатуры КАК Штрихкоды
        |ГДЕ
        |   Штрихкоды.Номенклатура В(&МассивНоменклатуры)";
    
    Запрос.УстановитьПараметр("МассивНоменклатуры", МассивНоменклатуры);
    Выборка = Запрос.Выполнить().Выбрать();
    
    Пока Выборка.Следующий() Цикл
        СтруктураЗаписи = Новый Структура("Штрихкод, Номенклатура, Характеристика, Упаковка");
        ЗаполнитьЗначенияСвойств(СтруктураЗаписи, Выборка);
        
        // Выгружаем запись по правилу конвертации регистра сведений
        ВыгрузитьПоПравилу(СтруктураЗаписи, , , , "ШтрихкодыНоменклатуры");
    КонецЦикла;
КонецЕсли;

Вариант 2. Выгрузка из ПКО «Номенклатура» с кэшированием

Если справочник Номенклатура выгружается полностью со всеми реквизитами (не только ссылкой), логичнее разместить код в обработчике «ПослеВыгрузки» ПКО Номенклатура. При этом важно помнить: платформа КД 2.0 автоматически отслеживает повторную выгрузку только для ссылочных данных. Независимый регистр сведений не имеет уникального идентификатора ссылки, поэтому одни и те же штрихкоды будут дублироваться в файле обмена при каждой повторной выгрузке позиции.

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

  1. В обработчике «ПередВыгрузкойДанных» глобальных правил создаем коллекцию для отслеживания: Параметры.Вставить("ОбработанныеШтрихкоды", Новый Соответствие);
  2. В обработчике «ПослеВыгрузки» ПКО Номенклатура проверяем наличие текущей ссылки в структуре кэша:
    
    Если Параметры.ОбработанныеШтрихкоды[Источник] = Неопределено Тогда
        Параметры.ОбработанныеШтрихкоды.Вставить(Источник, Истина);
        
        Запрос = Новый Запрос;
        Запрос.Текст = 
            "ВЫБРАТЬ
            |   Штрихкоды.Штрихкод КАК Штрихкод,
            |   Штрихкоды.Номенклатура КАК Номенклатура,
            |   Штрихкоды.Характеристика КАК Характеристика,
            |   Штрихкоды.Упаковка КАК Упаковка
            |ИЗ
            |   РегистрСведений.ШтрихкодыНоменклатуры КАК Штрихкоды
            |ГДЕ
            |   Штрихкоды.Номенклатура = &Номенклатура";
        
        Запрос.УстановитьПараметр("Номенклатура", Источник);
        Выборка = Запрос.Выполнить().Выбрать();
        
        Пока Выборка.Следующий() Цикл
            СтруктураЗаписи = Новый Структура("Штрихкод, Номенклатура, Характеристика, Упаковка");
            ЗаполнитьЗначенияСвойств(СтруктураЗаписи, Выборка);
            ВыгрузитьПоПравилу(СтруктураЗаписи, , , , "ШтрихкодыНоменклатуры");
        КонецЦикла;
    КонецЕсли;
    

Вариант 3. Выгрузка набором через процедуру ВыгрузитьРегистр()

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

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

Особенности загрузки независимых регистров в базе-приемнике

Обратим внимание на поведение данных при загрузке в целевой базе. Если выгрузка регистра выполняется не отдельными записями через менеджер записи, а набором записей, критически важно контролировать параметр Замещать:

  1. При установленном флаге Замещать = Истина неаккуратная запись набора с неполным составом измерений может полностью очистить существующие штрихкоды по другим аналитикам (например, по характеристикам или сериям).
  2. Если структура регистра в базе-приемнике отличается (например, добавлены новые обязательные измерения), необходимо в ПКО регистра в обработчике «ПриЗагрузке» или «ПередЗаписью» явно дозаполнить недостающие поля.
← На главную