Как правильно загружать единицы измерения при конвертации данных в 1С?

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

При настройке обмена данными между конфигурациями, использующими схожую структуру метаданных (например, Управление торговлей 10.3), разработчики часто сталкиваются с проблемой загрузки подчиненных справочников. Типичный пример — справочник ЕдиницыИзмерения, который подчинен справочнику Номенклатура. Проблема заключается в «циклической ссылке»: для создания единицы измерения нужен владелец (номенклатура), а в самой номенклатуре должны быть заполнены ссылки на единицы (хранения остатков, для отчетов). Рассмотрим, как решить эту задачу правильно с помощью инструментов «1С:Конвертация данных 2.1».

Суть проблемы «курицы и яйца»

Проанализируем ситуацию: в базе-приемнике при первой загрузке объекта Номенклатура система пытается заполнить реквизит ЕдиницаХраненияОстатков. Однако соответствующий элемент справочника ЕдиницыИзмерения еще не создан, так как он находится «дальше» по файлу выгрузки или требует уже записанного владельца для корректного поиска. В результате реквизиты номенклатуры остаются пустыми, и только при повторной загрузке, когда единицы уже физически существуют в базе, ссылки «схватываются». Мы разберем, как избежать двойного прохода и сделать загрузку корректной с первого раза.

Штатный механизм обработки ссылок в КД 2.1

Прежде всего, важно понять, что Конвертация данных умеет обрабатывать такие ситуации автоматически. Разберем механизм по шагам:

  1. При чтении XML-файла обработка УниверсальныйОбменДаннымиXML встречает объект Номенклатура.
  2. Если в реквизитах указана ссылка на ЕдиницыИзмерения, которой еще нет в базе, система создает «объект-пустышку» (битую ссылку) с тем внутренним идентификатором (GUID), который пришел из файла.
  3. Когда загрузчик доходит до раздела с данными самого справочника ЕдиницыИзмерения, он находит эту «пустышку» по GUID и наполняет её реальными данными (наименование, коэффициент, владелец).

Если этот механизм не срабатывает, значит, в настройках ПКО (Правил конвертации объектов) допущены ошибки. Рассмотрим наиболее частые причины сбоев.

Решение 1: Правильная настройка ПКО без программного кода

Как справедливо замечено в материалах форума, зачастую попытки «помочь» системе программным кодом в обработчиках только мешают. Выясним, какие настройки должны быть установлены для корректной работы:

Если поиск идет по полям (например, по владельцу и наименованию), система не сможет создать «пустышку» заранее, так как для поиска по полям объект уже должен быть записан. Поэтому для подчиненных справочников синхронизация по GUID является предпочтительной. Подробнее о возникающих в таких случаях особенностях можно узнать из заметок по нюансам конвертации данных без поиска по внутреннему идентификатору.

Решение 2: Порядок следования правил (ПВД и ПКО)

Рассмотрим влияние порядка правил на результат загрузки. В настройках конвертации у каждого ПКО есть параметр Порядок. Попробуем изменить приоритет:

  1. Если Номенклатура стоит выше ЕдиницИзмерения, то сначала создается «скелет» товара, затем загружаются его единицы. Это стандартная и наиболее стабильная схема.
  2. Если ЕдиницыИзмерения стоят выше, система может попытаться создать единицу раньше владельца. В этом случае она создаст «пустышку» для владельца.

На практике, если установлена синхронизация по внутреннему идентификатору, порядок ПКО не играет решающей роли, но для визуального контроля и логики процесса лучше располагать основные справочники выше подчиненных. Для предварительной проверки структуры сформированного XML-файла подойдёт обработка для анализа состава выгруженных данных.

Анализ программных обработчиков

Иногда разработчики пытаются использовать обработчик ПослеЗагрузки для принудительной установки связей. Проанализируем типичный пример кода, который может привести к ошибкам:


Если НЕ Объект.ЭтоГруппа И ЗначениеЗаполнено(Объект.БазоваяЕдиницаИзмерения) Тогда
    ВыборкаЕдиниц = Справочники.ЕдиницыИзмерения.Выбрать(, Объект.Ссылка);
    Если ВыборкаЕдиниц.Следующий() Тогда
        НайденнаяЕдиница = ВыборкаЕдиниц.Ссылка;
        Объект.ЕдиницаХраненияОстатков = НайденнаяЕдиница;
    КонецЕсли;
КонецЕсли;

Почему этот код часто не работает при первой загрузке?

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

Как сделать правильно, если штатный механизм не подходит?

Если по каким-то причинам (например, отсутствие GUID в источнике) штатный механизм не справляется, и вы решили использовать код, воспользуйтесь следующими рекомендациями:

Итоговый алгоритм настройки

Выясним краткую последовательность действий для успешного обмена:

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

Следуя этим правилам, вы обеспечите корректную загрузку всех связей с первого раза, избежав дублирования данных и «пустых» реквизитов в карточке товара.

← На главную