При разработке управляемых форм в платформе «1С:Предприятие 8.3» начинающие программисты часто сталкиваются с ошибкой компиляции: «Процедура или функция с указанным именем не определена (РольДоступна)». Эта ошибка возникает при попытке вызвать метод проверки роли непосредственно в клиентском коде (в процедуре с директивой компиляции &НаКлиенте).
В этой статье мы подробно разберем, почему возникает данная проблема, рассмотрим классическое решение, предложенное на форуме, а также изучим лучшие практики и стандарты разработки «1С», которые помогут сделать ваш код быстрым, безопасным и отказоустойчивым.
Давайте проанализируем ситуацию. Платформенный метод РольДоступна() предназначен для проверки того, назначена ли текущему пользователю определенная роль безопасности. Согласно синтакс-помощнику «1С», данный метод имеет следующую доступность:
Как мы видим, в списке отсутствует тонкий клиент и веб-клиент. Управляемые формы работают именно в тонком или веб-клиенте. Пытаясь вызвать этот метод внутри клиентской процедуры (например, в обработчике события ПередНачаломДобавления табличной части), мы обращаемся к функции, которая на клиенте попросту не существует. Платформа не может скомпилировать этот код и сообщает об ошибке.
Ниже мы пошагово разберем три различных способа решения этой задачи — от простого обходного пути до профессиональных стандартов разработки «1С».
Самый очевидный способ обойти это ограничение — делегировать проверку роли серверу. Для этого мы можем создать небольшую функцию-обертку в модуле формы с директивой компиляции &НаСервереБезКонтекста. Этот метод не тянет за собой на сервер данные всей формы (контекст), что делает вызов более легким.
Давайте посмотрим на практический пример реализации этого подхода:
&НаСервереБезКонтекста
Функция ДоступнаРольНачальникМТС()
Возврат РольДоступна("НачальникМТС");
КонецФункции
&НаКлиенте
Процедура ТабличнаяЧастьПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа, Параметр)
// Вызываем нашу серверную функцию вместо встроенного метода
Если ДоступнаРольНачальникМТС() Тогда
Отказ = Истина;
ПоказатьПредупреждение(, "У вас недостаточно прав для добавления новых строк!");
КонецЕсли;
КонецПроцедуры
Преимущества решения: Простота реализации, код пишется за пару минут.
Недостатки решения: Серьезные проблемы с производительностью (о них ниже).
Давайте проанализируем, как работает Решение 1 на практике. Каждый раз, когда пользователь будет нажимать кнопку «Добавить» или клавишу Insert в табличной части, система будет выполнять сетевой вызов (round-trip) к серверу 1С для проверки роли. Если у пользователя нестабильный интернет, пинг до сервера высокий или база данных сильно нагружена, интерфейс программы начнет заметно «подвисать» при нажатии кнопки добавления строки. Пользователь будет испытывать дискомфорт.
Чтобы избежать лишних серверных вызовов в интерфейсных событиях, мы применим правильный архитектурный паттерн: однократная проверка при создании формы.
Разберем этот метод по шагам:
ДоступнаРольНачальникМТС и типом данных Булево.ПриСозданииНаСервере один раз инициализируйте этот реквизит.Посмотрим, как выглядит программный код для этого решения:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Проверяем роль один раз при открытии формы и записываем в реквизит
ДоступнаРольНачальникМТС = РольДоступна("НачальникМТС");
КонецПроцедуры
&НаКлиенте
Процедура ТабличнаяЧастьПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа, Параметр)
// Проверка происходит мгновенно на клиенте, серверных вызовов нет!
Если ДоступнаРольНачальникМТС Тогда
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Этот способ является наиболее предпочтительным для мобильных клиентов, веб-клиентов и распределенных баз данных, так как полностью исключает лишний сетевой трафик при работе пользователя с табличной частью.
Если ваша конфигурация разработана на базе БСП (а это практически все современные типовые решения фирмы «1С», такие как ERP, УТ, БП, ЗУП, УНФ), использовать напрямую платформенный метод РольДоступна() крайне не рекомендуется.
Платформенный метод имеет одну неприятную особенность: если у пользователя назначена роль «ПолныеПрава», но при этом физически в его профиле безопасности не стоит галочка напротив роли «НачальникМТС», метод РольДоступна("НачальникМТС") вернет Ложь. В результате системный администратор с полными правами не сможет выполнить действие, которое ему по логике должно быть доступно.
В БСП эта проблема решена. Для проверки прав следует использовать специальную экспортную функцию общего модуля Пользователи.РолиДоступны(). Она автоматически учитывает наличие полных прав и суперпользователей.
Пример кода с использованием БСП при создании формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// БСП корректно обработает администраторов и привилегированный режим
ДоступнаRoleНачальникМТС = Пользователи.РолиДоступны("НачальникМТС");
КонецПроцедуры
Важно помнить критически важное правило разработки в «1С»: любые проверки прав на форме (в клиентском коде) служат исключительно для удобства интерфейса (UI/UX). Они не защищают базу данных от несанкционированной записи.
Опытный пользователь или программист может легко обойти проверку в событии формы ПередНачаломДобавления (например, программно записав объект через внешнюю обработку или изменив значение переменной в отладчике). Поэтому, если ограничение на добавление строк критично для бизнес-логики предприятия, проверка прав обязательно должна дублироваться на сервере — в модуле самого объекта (например, в обработчике события ПередЗаписью документа или справочника).
Используйте кэширование ролей в реквизитах формы и функции БСП, чтобы ваши управляемые формы работали быстро, корректно и соответствовали высоким стандартам разработки фирмы «1С»!