Как в 1С проверить, хватает ли у пользователя прав на просмотр документа перед открытием формы?

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

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

Способ 1. Проверка прав на уровне метаданных с помощью функции ПравоДоступа

Для базовой проверки наличия прав в платформе 1С предусмотрен метод глобального контекста ПравоДоступа. Проанализируем синтаксис этой функции:

ПравоДоступа(<Право>, <ОбъектМетаданных>, [<Пользователь/Роль>], [<СтандартныйРеквизит/СтандартнаяТабличнаяЧасть>])

Обратим внимание на следующие ключевые параметры:

  1. Право — проверяемое право (строка). Для открытия формы интерактивно важны права "Просмотр" (интерактивный доступ) и "Чтение" (доступ к данным на чтение).
  2. ОбъектМетаданных — объект метаданных документа (получается через свойство Метаданные() ссылки или конкретной ветки конфигурации).
  3. Пользователь/Роль — необязательный параметр. Если его опустить, проверка будет производиться для текущего пользователя информационной базы.

Посмотрим на пример обхода массива документов с предварительной проверкой прав:


Для Каждого ДокументСсылка Из МассивДокументов Цикл
    МетаданныеДокумента = ДокументСсылка.Метаданные();
    
    // Проверяем наличие прав на просмотр и чтение на уровне ролей
    Если ПравоДоступа("Просмотр", МетаданныеДокумента) И ПравоДоступа("Чтение", МетаданныеДокумента) Тогда
        ФормаДокумента = ДокументСсылка.ПолучитьФорму();
        ФормаДокумента.Открыть();
    КонецЕсли;
КонецЦикла;

Важное ограничение: функция ПравоДоступа проверяет исключительно права ролей, назначенных пользователю. Если в конфигурации настроено ограничение доступа на уровне записей (RLS — Record Level Security), данная функция вернет Истина, однако при попытке прочитать конкретный экземпляр документа доступ может быть заблокирован.

Способ 2. Проверка ограничений на уровне записей (RLS) через запрос с ключевым словом РАЗРЕШЕННЫЕ

Если в системе активно разграничение прав на уровне записей (например, по организациям, подразделениям или группам доступа), то для проверки конкретного документа ссылки метод ПравоДоступа окажется недостаточным. Выясним причину: право на объект метаданных в целом у пользователя есть, а вот на чтение конкретной строки таблицы базы данных — нет.

В такой ситуации наиболее надежным и быстрым платформенным решением выступает запрос с ключевым словом РАЗРЕШЕННЫЕ. Если у пользователя нет прав RLS на данную запись, запрос не упадет с ошибкой, а вернет пустую таблицу.

Разберем по шагам, как проверить доступность ссылки универсальным запросом:


Функция ДокументДоступенДляЧтения(СсылкаНаДокумент)
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ РАЗРЕШЕННЫЕ
        |   Док.Ссылка КАК Ссылка
        |ИЗ
        |   " + СсылкаНаДокумент.Метаданные().ПолноеИмя() + " КАК Док
        |ГДЕ
        |   Док.Ссылка = &Ссылка";
    
    Запрос.УстановитьПараметр("Ссылка", СсылкаНаДокумент);
    Выборка = Запрос.Выполнить().Выбрать();
    
    Возврат Выборка.Следующий();
КонецФункции

Используем этот метод перед открытием формы:


Для Каждого ДокументСсылка Из МассивДокументов Цикл
    Если ПравоДоступа("Просмотр", ДокументСсылка.Метаданные()) Тогда
        Если ДокументДоступенДляЧтения(ДокументСсылка) Тогда
            Форма = ДокументСсылка.ПолучитьФорму();
            Форма.Открыть();
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

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

Способ 3. Перехват исключения при открытии формы

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

В обычном приложении для гарантированной непрерывности пакетной обработки можно обернуть операцию открытия в конструкцию Попытка ... Исключение:


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

Таким образом, комбинация проверки метаданных с помощью ПравоДоступа, фильтрации RLS через ВЫБРАТЬ РАЗРЕШЕННЫЕ и безопасного блока Попытка позволяет полностью защитить алгоритм от прерывания системными сообщениями об отказе в доступе.

← На главную