Почему возникает ошибка прав доступа при программном удалении документа в 1С и как её исправить?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей IT и автоматизация бизнеса
← На главную

При попытке программно удалить документ из базы данных с помощью метода Удалить() разработчики часто сталкиваются с ошибкой прав доступа. Даже если текущему пользователю назначена роль с явным разрешением на интерактивное и программное удаление конкретного документа, платформа 1С:Предприятие может выдать отказ в доступе.

Разберем причины такого поведения платформы и проанализируем проверенные варианты решения этой проблемы.

Выясняем причину ошибки

Проанализируем, что происходить на уровне платформы при вызове метода Удалить(). Когда выполняется физическое удаление объекта типа ДокументОбъект, система удаляет не только саму запись из таблицы документов в СУБД. Автоматически происходит очистка всех связанных данных:

  1. Движений документа по регистрам накопления, сведений, бухгалтерии и расчета.
  2. Записей в служебных регистрах подсистемы разграничения прав (например, регистры ключей доступа в конфигурациях на базе БСП, таких как 1С:Управление торговлей 11).

Если в журнале регистрации (ЖР) проверить запись об ошибке, станет понятно, что платформа ругается вовсе не на сам документ, а на отсутствие прав на изменение или удаление записей в одном из сопутствующих или служебных регистров.

Рассмотрим основные способы корректного программного удаления объектов в 1С.

Решение 1. Использование привилегированного режима на сервере

Самый безопасный и правильный способ выполнения административных манипуляций с данными от имени обычного пользователя — это переход в привилегированный режим на стороне сервера. В этом режиме платформа временно отключает проверку прав доступа и механизмы RLS (разграничение доступа на уровне записей).

Посмотрим на пример кода в модуле объекта или менеджера, выполняемого на сервере:


УстановитьПривилегированныйРежим(Истина);

Попытка
    ДокументОбъект.Удалить();
Исключение
    ЗаписьЖурналаРегистрации("УдалениеДокумента", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
КонецПопытки;

УстановитьПривилегированныйРежим(Ложь);

Важно: Метод УстановитьПривилегированныйРежим() работает только в серверном контексте. При вызове на клиенте он не окажет никакого эффекта.

Решение 2. Вынос логики удаление в привилегированный общий модуль

Если операция удаления вызывается из клиентского контекста или внешней обработки, лучшей практикой будет создание процедуры в общем модуле с установленным флагом Привилегированный.

Разберем по шагам создание такой процедура:

  1. Создадим новый общий модуль (или используем существующий серверный модуль).
  2. В свойствах модуля установим флаги Сервер и Привилегированный.
  3. Поместим в модуль процедуру физического удаления документа:

// Процедура размещается в привилегированном общем модуле
Процедура УдалитьДокументНаСервере(СсылкаНаДокумент) Экспорт
    
    ОбъектДокумент = СсылкаНаДокумент.ПолучитьОбъект();
    Если ОбъектДокумент <> Неопределено Тогда
        ОбъектДокумент.Удалить();
    КонецЕсли;

КонецПроцедуры

Вызов процедур из привилегированного модуля автоматически отключает проверку прав текущего пользователя при выполнении операций с базой данных внутри этого модуля.

Решение 3. Расширение прав роли пользователя

Если политика безопасности предприятия запрещает использование привилегированного режима, необходимо предоставить роли пользователя доступ ко всем регистрам, затрагиваемым при удалении. Для этого проанализируем состав движений документа и найдем все связанные объекты:

  1. Откроем конфигуратор и найдем нужный документ.
  2. На вкладке Движения посмотрим список регистров, в которые документ делает записи.
  3. В роли пользователя предоставим права Изменение и Запись для каждого из этих регистров.
  4. Если конфигурация использует БСП, также потребуется предоставить права на служебные регистры прав (например, ЗаписиКлючейДоступа).

Альтернативный вариант: пометка на удаление

Физическое удаление документов методом Удалить() удаляет объект напрямую из базы СУБД без контроля ссылочной целостности. Это может привести к появлению «битых ссылок» в других документах и отчетах. Если стоящая задача позволяет, рекомендуется замещать прямое удаление установкой пометки на удаление с помощью метода УстановитьПометкуУдаления():


ОбъектДокумент = СсылкаНаДокумент.ПолучитьОбъект();
ОбъектДокумент.УстановитьПометкуУдаления(Истина);

Установка пометки удаления не требует расширенных прав на физическую очистку таблиц регистров и позволяет безопасно удалить объект штатным интерактивным удалением помеченных объектов.

← На главную