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