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