Почему возникает ошибка Нарушение прав доступа при проведении документа, созданного на основании?

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

Нередко разработчики и администраторы 1С сталкиваются с парадоксальной ситуацией: пользователь под своими правами может вручную создать и провести документ (например, Расходный кассовый ордер), но если этот же документ создается программно на основании другого (например, Поступление товаров и услуг), система выдает ошибку «Нарушение прав доступа!». При этом права на создание и проведение самого документа у пользователя явно есть. В этой статье мы подробно разберем, почему так происходит, как диагностировать проблему и какими методами ее можно решить, сохранив безопасность системы.

Анализируем причину через Журнал регистрации

Первым делом при возникновении любых ошибок с правами доступа нам необходимо обратиться к инструменту Журнал регистрации. Ошибка в интерфейсе часто бывает малоинформативной, но системный лог хранит подробности. Проанализируем последовательность действий для поиска причины:

  1. Откроем Журнал регистрации (Меню: Сервис — Журнал регистрации или через Конфигуратор).
  2. Установим фильтр по текущему пользователю и событию «Отказ в доступе».
  3. Найдем запись, соответствующую моменту возникновения ошибки.

Как правило, в колонке «Данные» или в описании события будет указано конкретное право, которого не хватило пользователю. В рассматриваемом нами случае это право — «Интерактивное изменение проведенных». Это дает нам важную зацепку: несмотря на то, что мы создаем новый документ, система по какой-то причине пытается изменить уже существующий и проведенный родительский документ.

Выясняем, почему меняется родительский документ

Рассмотрим механизм «проталкивания» изменений. Когда мы создаем РКО на основании ПТиУ, конфигурация может пытаться обновить связи между ними. Рассмотрим основные причины, по которым это происходит:

Посмотрим на пример кода, который часто становится причиной проблемы:


Режим = РежимДиалогаВопрос.ДаНетОтмена;
Ответ = Вопрос("Сформировать документ оплаты по этому документу?", Режим, 0);
Если Ответ = КодВозвратаДиалога.Да Тогда
    НовДок = Документы.РасходныйКассовыйОрдер.СоздатьДокумент();
    ЗаполнитьЗначенияСвойств(НовДок, Источник); // Копируем всё подряд
    НовДок.Дата = ТекущаяДата();
    // ... заполнение табличных частей ...
    НовДок.ПолучитьФорму("ФормаДокумента").Открыть();
КонецЕсли;

Использование ЗаполнитьЗначенияСвойств(НовДок, Источник) копирует все совпадающие по именам реквизиты. Если среди них есть системные поля или специфические ссылки, которые при записи нового документа инициируют проверку прав на «Источник», это может заблокировать процесс.

Способ решения №1: Использование стандартного механизма заполнения

Проанализируем более правильный подход. В 1С рекомендуется создавать документы через метод Заполнить(Основание). Это инициирует обработчик ОбработкаЗаполнения в модуле объекта создаваемого документа. Разработчики типовых решений обычно закладывают в этот обработчик правильную логику, которая минимизирует риски блокировки по правам.

Рассмотрим пример правильного вызова:


НовДок = Документы.РасходныйКассовыйОрдер.СоздатьДокумент();
НовДок.Заполнить(Источник); // Вызывает ОбработкаЗаполнения в модуле РКО
НовДок.Дата = ТекущаяДата();
НовДок.ПолучитьФорму("ФормаДокумента").Открыть();

Важный момент: Если ошибка сохраняется, проверьте код внутри процедуры ОбработкаЗаполнения в модуле документа РасходныйКассовыйОрдер. Если там происходит обращение к методу Записать() для объекта-основания, это и есть причина ошибки прав.

Способ решения №2: Привилегированный режим

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

Привилегированный режим позволяет коду игнорировать проверку прав доступа на время выполнения операции. Выясним, как это реализовать программно:


УстановитьПривилегированныйРежим(Истина);
// Здесь выполняется код, который должен изменить статус родителя 
// или записать технические данные, к которым у пользователя нет доступа.
ИсточникОбъект = Источник.ПолучитьОбъект();
ИсточникОбъект.СтатусОплаты = Перечисления.СтатусыОплаты.Оплачен;
ИсточникОбъект.Записать(РежимЗаписиДокумента.Запись); 
УстановитьПривилегированныйРежим(Ложь);

Рассмотрим нюанс: УстановитьПривилегированныйРежим работает только на стороне сервера или в модулях, имеющих доступ к серверному контексту. Если вы работаете в «Обычных формах» в толстом клиенте, этот метод может не сработать в модуле формы. В таком случае логику записи нужно выносить в процедуру модуля объекта или модуля менеджера, помеченную как серверная.

Способ решения №3: Контроль подписок на события

Проанализируем еще одну скрытую причину — Подписки на события. В современных конфигурациях часто существуют глобальные обработчики (например, ПередЗаписью или ПриЗаписи), которые срабатывают автоматически для всех документов. Если при создании РКО какая-то подписка пытается обратиться к родительскому ПТиУ для пересчета его итогов или записи в дополнительные регистры сведений, это вызовет ошибку прав, даже если ваш основной код кажется «чистым».

Чтобы проверить эту версию, выполните следующие шаги:

  1. Найдите в дереве конфигурации раздел «Общие» — «Подписки на события».
  2. Отфильтруйте подписки, в качестве источника которых указан ваш документ (например, РасходныйКассовыйОрдер).
  3. Проверьте код в процедурах этих подписок на предмет записи или изменения других объектов.

Влияние ограничений на уровне записей (RLS)

Выясним роль RLS (Record Level Security). Ошибка «Нарушение прав доступа» может возникать, если пользователь имеет право создавать РКО, но не имеет прав на чтение определенного реквизита, который автоматически подставился из ПТиУ. Например, это может быть Касса или Банковский счет, закрепленный за подразделением, к которому у пользователя нет доступа.

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

Подведем итоги

Для исправления ошибки «Нарушение прав доступа!» при создании документов на основании, мы рекомендуем придерживаться следующего алгоритма:

Следуя этим правилам, вы сможете реализовать удобный механизм создания документов «в один клик», не нарушая при этом строгую политику безопасности прав доступа в 1С.

← На главную