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