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