Почему в Конвертации данных 2.0 единицы измерения переносятся, но не подставляются в номенклатуру?

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

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

Выясним причину такого поведения платформы и разберем по шагам рабочие способы исправления этой ошибки.

Причина проблемы: циклическая зависимость и подчинение объектов

Проанализируем структуру типовых метаданных (например, в УПП 1.3 или УТ 10.3). Справочник ЕдиницыИзмерения является подчиненным: он не может существовать без заполненного реквизита Владелец. В то же время сам справочник Номенклатура ссылается на подчиненные единицы измерения в своих реквизитах.

Возникает классическая циклическая связь (deadlock ссылок):

  1. Платформа 1С не может записать подчиненный элемент ЕдиницыИзмерения, пока в базе-приемнике физически не записан его Владелец (номенклатура).
  2. Номенклатура при загрузке пытается сослаться на единицы хранения остатков и отчетов, которых в базе-приемнике еще нет.
  3. Если единица измерения выгружается по ссылке из табличной части документа или регистра (например, Штрихкоды), она может сериализоваться в сокращенном виде — только с ключевыми полями поиска, без передачи реквизита Владелец. В результате в базе-приемнике сопоставление дает сбой.

Рассмотрим подробнее способы решения этой коллизии в «Конвертации данных 2.0».

Способ 1. Настройка ПКО для реквизита «Владелец» с составным типом

Разберем базовую настройку ПКС для реквизита Владелец в правиле конвертации справочника ЕдиницыИзмерения. Если у реквизита Владелец тип составной (например, Номенклатура и НоменклатурныеГруппы), прямое указание одного ПКО в правиле невозможно.

В этом случае в ПКС Владелец справочника ЕдиницыИзмерения открываем обработчик ПередВыгрузкой и динамически определяем имя правила конвертации в зависимости от типа источника:


Если ТипЗнч(Источник.Владелец) = Тип("СправочникСсылка.Номенклатура") Тогда
    ИмяПКО = "Номенклатура";
ИначеЕсли ТипЗнч(Источник.Владелец) = Тип("СправочникСсылка.НоменклатурныеГруппы") Тогда
    ИмяПКО = "НоменклатурныеГруппы";
КонецЕсли;

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

Способ 2. Разделение правил конвертации (создание дублирующего ПКО)

Посмотрим на практический прием, позволяющий быстро обойти кеширование и зацикливание выгрузки ссылок внутри «Конвертации данных»:

  1. Создадим копию правила конвертации объектов ЕдиницыИзмерения, назвав ее, например, ЕдиницыИзмерения_ДляНоменклатуры.
  2. В основном ПКО Номенклатура для реквизитов ЕдиницаХраненияОстатков и ЕдиницаДляОтчетов укажем созданное правило ЕдиницыИзмерения_ДляНоменклатуры.
  3. Для табличных частей документов и регистров сведений оставим стандартное ПКО ЕдиницыИзмерения.

Разделение правил исключает ситуацию, когда механизм выгрузки берет объект из внутреннего кеша уже выгруженных неполных ссылок без владельца.

Способ 3. Отключение запоминания выгруженных объектов

Если подчиненные единицы измерения выгружаются раньше номенклатуры (например, при выгрузке по ссылкам из табличных частей документов), механизм КД 2 может запомнить неполную ссылку.

Откроем ПКО ЕдиницыИзмерения, перейдем на вкладку Настройки и установим флаг Не запоминать выгруженные объекты. Это заставит обработку каждый раз повторно анализировать и полностью выгружать объект со всеми его реквизитами, включая владельца.

Способ 4. Двухэтапная установка реквизитов через обработчики событий (рекомендуемый)

Наиболее надежный архитектурный подход заключается в разрыве циклической связи на этапе переноса данных:

  1. В ПКО Номенклатура отключим передачу реквизитов ЕдиницаХраненияОстатков и ЕдиницаДляОтчетов (снимем флаги активности с соответствующих ПКС). Переносим только БазоваяЕдиницаИзмерения (так как это независимый классификатор ОКЕИ).
  2. Справочник ЕдиницыИзмерения переносим штатно: номенклатура-владелец к этому моменту уже успешно создана в базе-приемнике, поэтому подчиненные единицы записываются без платформенных ошибок.
  3. В ПКО Номенклатура в обработчике ПослеЗагрузки или ПослеЗаписиОбъекта программно находим подчиненные единицы и подставляем их в номенклатуру:

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

Способ 5. Передача контекста владельца через ИсходящиеДанные

Если единица измерения выгружается из строковой части документа, где нет прямого реквизита Владелец (он берется из соседней колонки Номенклатура), используем механизм передачи контекста:

  1. В ПКС табличной части документа для реквизита ЕдиницаИзмерения в обработчике ПередВыгрузкой формируем структуру:

ИсходящиеДанные = Новый Структура("Владелец", СтрокаТабличнойЧасти.Номенклатура);
  1. В ПКО ЕдиницыИзмерения для свойства Владелец устанавливаем флаг Получить из входящих данных.

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

← На главную