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