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