Как программно создать напоминание пользователю в 1С:БСП и исправить ошибку «Отказ в доступе»?

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

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

Выясним причину ошибки: почему права есть, а доступа нет?

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

Основная причина кроется в использовании RLS (Record Level Security) — ограничении прав на уровне записей. В типовых конфигурациях (УТ 11, ERP, КА) роль «Добавление и изменение напоминаний» имеет жесткое условие. Если мы заглянем в шаблон ограничений этой роли для регистра НапоминанияПользователя, то увидим конструкцию, эквивалентную следующей:

ГДЕ Пользователь = &ТекущийПользователь

Это означает, что обычный пользователь имеет право создавать, изменять и удалять записи в этом регистре только для самого себя. Как только ваш код пытается программно назначить напоминание другому пользователю (например, руководителю или коллеге), механизм RLS блокирует транзакцию, так как текущий сеанс не обладает правами на модификацию «чужих» данных.

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

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

Для обхода RLS код записи должен выполняться в привилегированном режиме. Рассмотрим пример корректировки кода, предложенного автором темы:


// Устанавливаем привилегированный режим, чтобы обойти ограничения RLS
УстановитьПривилегированныйРежим(Истина);

МенеджерЗаписи = РегистрыСведений.НапоминанияПользователя.СоздатьМенеджерЗаписи();

МенеджерЗаписи.Пользователь = ПолучательНапоминания; // Здесь может быть любой пользователь
МенеджерЗаписи.Источник = СсылкаНаОбъект;
МенеджерЗаписи.ВремяСобытия = ТекущаяДата() + 60;
МенеджерЗаписи.Описание = ОписаниеНапоминания;
МенеджерЗаписи.СрокНапоминания = ТекущаяДата() + 60;
МенеджерЗаписи.СпособУстановкиВремениНапоминания = Перечисления.СпособыУстановкиВремениНапоминания.ВУказанноеВремя;
МенеджерЗаписи.ИнтервалВремениНапоминания = 0;

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

// Обязательно отключаем привилегированный режим после завершения операции
УстановитьПривилегированныйРежим(Ложь);

Важный нюанс: использование УстановитьПривилегированныйРежим(Истина) работает только в коде, исполняемом на стороне сервера. Если ваш код вызывается из модуля объекта (например, ПередЗаписью), это условие соблюдается.

Решение 2: Использование стандартного API БСП

В современных версиях БСП разработчики предусмотрели штатные процедуры для работы с напоминаниями. Вместо прямого обращения к менеджеру записи регистра, рекомендуется использовать методы общего модуля НапоминанияПользователя. Проанализируем преимущества этого подхода: система сама заполнит необходимые реквизиты и выполнит проверки.

Пример использования штатного метода:


ПараметрыНапоминания = НапоминанияПользователя.ПараметрыНапоминания();
ПараметрыНапоминания.Пользователь = ПолучательНапоминания;
ПараметрыНапоминания.ВремяСобытия = ТекущаяДата() + 3600; // Через час
ПараметрыНапоминания.Описание = "Проверить статус заказа";
ПараметрыНапоминания.СпособУстановкиВремени = Перечисления.СпособыУстановкиВремениНапоминания.ВУказанноеВремя;

// Вызов программного интерфейса
НапоминанияПользователя.УстановитьНапоминание(ПараметрыНапоминания);

Однако помните, что даже штатные методы БСП могут подчиняться RLS, если внутри них не предусмотрен переход в привилегированный режим. В случае с напоминаниями «другому лицу» использование обертки в виде УстановитьПривилегированныйРежим(Истина) остается актуальным.

Проблема использования СсылкаНового

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

Рекомендация: перенесите логику создания напоминания в событие ПриЗаписи. На этом этапе ссылка объекта уже гарантированно существует в базе данных, и запись в регистр сведений будет корректной. Посмотрим на правильную структуру вызова:


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

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

Для успешного программного создания напоминаний в типовых конфигурациях необходимо придерживаться следующих правил:

  1. Учитывать RLS: Помните, что обычный пользователь ограничен в правах на запись чужих напоминаний.
  2. Использовать серверные модули: Операции записи должны происходить на сервере в привилегированном режиме.
  3. Работать с существующими ссылками: Избегайте привязки напоминаний к СсылкаНового в пользу событий ПриЗаписи.
  4. Соблюдать структуру регистра: Не забывайте заполнять обязательные поля, такие как СпособУстановкиВремениНапоминания, иначе запись может не отобразиться в списке активных напоминаний пользователя.

Соблюдение этих архитектурных принципов позволит вам избежать ошибок доступа и сделать работу пользователей в системе более эффективной.

← На главную