При разработке и администрировании баз данных на платформе 1С:Предприятие часто возникает задача удаления родительских записей или отвязки подчиненных элементов от их текущего владельца. Разберем по шагам, как устроена работа с подчиненными справочниками, можно ли сделать поле владельца пустым и как корректно выполнить удаление объектов без нарушения ссылочной целостности базы данных.
Проанализируем базовую концепцию подчинения в платформе 1С. В структуре метаданных существует разграничение между двумя понятиями:
Родитель = ПустаяСсылка()).Для подчиненного справочника системный реквизит Владелец является обязательным на уровне платформы и СУБД. Платформа физически не позволяет записать элемент подчиненного справочника со значением Неопределено или ПустаяСсылка() в поле владельца. При попытке программного вызова метода Записать() без заполненного владельца будет вызвано системное исключение.
Рассмотрим типовую ситуацию: вам требуется удалить элемент-владелец (например, контрагента или договор), у которого есть подчиненные элементы. Если подчиненные данные больше не нужны, правильный алгоритм выглядит следующим образом:
Контроль ссылочной целостности 1С не позволит удалить объект-владелец до тех пор, пока на него ссылаются подчиненные записи. Поэтому сначала удаляются подчиненные строки, либо они удаляются платформой совместно в одной транзакции.
Если подчиненные элементы необходимо сохранить в системе, но их текущего владельца нужно удалить, очистить реквизит нельзя, но можно указать другого владельца. Разберем, как это реализовать:
Посмотрим на пример программной смены владельца:
Выборка = Справочники.ДоговорыКонтрагентов.Выбрать(, СтарыйКонтрагент);
Пока Выборка.Следующий() Цикл
ОбъектДоговор = Выборка.ПолучитьОбъект();
ОбъектДоговор.Владелец = НовыйКонтрагентАрхив;
ОбъектДоговор.Записать();
КонецЦикла;
Если по логике бизнес-процесса запись справочника должна существовать автономно и лишь опционально ссылаться на другой объект, механизм подчинения справочников в конфигураторе использовать не следует. Рассмотрим альтернативное решение:
Контрагент).В этом случае реквизит может оставаться незаполненным, его можно очищать в любой момент, а удаление связанного объекта не будет вызывать жестких системных блокировок.
Выясним причину, почему нельзя применять непосредственное удаление через метод Удалить() без контроля целостности. Если удалить объект-владелец напрямую, подчиненные записи останутся в базе, но в поле Владелец появится битая ссылка вида <Объект не найден...>.
Наличие таких записей приводит к ошибкам при динамических отборах в формах списков, сбоям в планах обмена и некорректной работе отчетов. Для исправления последствий прямого удаления потребуется выполнение административной процедуры Тестирование и исправление с режимом проверки ссылочной целостности.