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