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

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

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

Причины возникновения ошибки контекста

Проанализируем архитектуру клиент-серверного взаимодействия в платформе 1С:Предприятие 8.3, чтобы понять корень проблемы:

  1. Ограничение метода глобального контекста: функция РольДоступна() существует только на стороне сервера (а также в толстом клиенте и внешнем соединении). На тонком клиенте и в веб-клиенте этой функции нет в глобальном контексте.
  2. Специфика директивы &НаКлиентеНаСервереБезКонтекста: процедуры и функции с такой директивой компилируются дважды — отдельно для клиента и отдельно для сервера. При исполнении на клиенте такая процедура не может напрямую обращаться к методам, объявленным с директивами &НаСервере или &НаСервереБезКонтекста того же модуля формы, а также не видит серверные методы глобального контекста.
  3. Настройки общих модулей: если серверная функция выносится в общий модуль, у которого установлен признак Сервер, но отсутствует признак Вызов сервера, клиентский код не сможет вызвать этот метод напрямую.

Вариант 1. Использование неконтекстной серверной функции модуля формы

Если логика управления доступностью элементов формы реализована в виде клиентской процедуры или смешанной процедуры с директивой &НаКлиентеНаСервереБезКонтекста, для проверки роли необходимо добавить отдельную функцию с директивой &НаСервереБезКонтекста в этот же модуль формы.

Рассмотрим пример реализации:


&НаСервереБезКонтекста
Функция ПроверитьДоступностьРоли(ИмяРоли)
    Возврат РольДоступна(ИмяРоли);
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Процедура УстановитьДоступность(Форма, Объект)
    // Если требуется проверить роль внутри безконтекстной процедуры:
    // На сервере метод отработает напрямую, на клиенте потребуется передача состояния
КонецПроцедуры

Обратите внимание: если вызывающая процедура объявлена как &НаКлиенте, вызов ПроверитьДоступностьРоли() выполнит быстрый неконтекстный серверный вызов и вернет булево значение.

Вариант 2. Вызов серверного общего модуля с признаком вызова сервера

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

  1. В дереве метаданных открываем свойства общего модуля (например, УправлениеДоступомСервер).
  2. Устанавливаем флаги: Сервер и Вызов сервера.
  3. Создаем экспортную функцию проверки:

Функция ПроверитьНаличиеРоли(ИмяРоли) Экспорт
    Возврат РольДоступна(ИмяРоли);
КонецФункции

Теперь эту функцию можно беспрепятственно вызывать из клиентских процедур управляемых форм:


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    Если УправлениеДоступомСервер.ПроверитьНаличиеРоли("СуперРоль") Тогда
        Элементы.ГруппаСпецРеквизиты.Доступность = Истина;
    КонецЕсли;
КонецПроцедуры

Вариант 3. Оптимальный подход: кэширование прав в реквизитах формы

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

Разберем реализацию этого шаблона:

  1. Добавляем в реквизиты управляемой формы новый реквизит РазрешеноРедактирование с типом Булево.
  2. В обработчике ПриСозданииНаСервере вычисляем доступность роли и сохраняем результат в реквизит формы:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    РазрешеноРедактирование = РольДоступна("СуперРоль");
    УстановитьДоступностьЭлементов();
КонецПроцедуры
  1. На клиенте при любых интерактивных событиях опираемся на значение сохраненного реквизита без обращения к серверу:

&НаКлиенте
Процедура УстановитьДоступностьНаКлиенте()
    Если Объект.Проведен И Не РазрешеноРедактирование Тогда
        Элементы.РеквизитСпец.Доступность = Ложь;
    Иначе
        Элементы.РеквизитСпец.Доступность = Истина;
    КонецЕсли;
КонецПроцедуры

Использование функций Библиотеки Стандартных Подсистем (БСП)

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


&НаКлиенте
Процедура ПроверитьПраваБСП()
    Если ПользователиКлиентСервер.ЕстьРоль("СуперРоль") Тогда
        // Разрешаем выполнение операций
    КонецЕсли;
КонецПроцедуры

Такой подход обеспечивает максимальное быстродействие интерфейса и чистоту исходного кода.

← На главную