Как отобразить данные регистра в динамическом списке, если у пользователя нет прав на просмотр?

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

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

Анализ проблемы: почему исчезают колонки?

Рассмотрим типичную конфигурацию. У нас есть справочник Справочник.Сотрудники и регистр сведений РегистрСведений.Зарплата. В динамическом списке справочника прописан запрос с левым соединением:


ВЫБРАТЬ
    СправочникСотрудники.Ссылка КАК Ссылка,
    СправочникСотрудники.Код КАК Код,
    СправочникСотрудники.Наименование КАК Наименование,
    Зарплата.РазмерЗарплаты КАК РазмерЗарплаты,
    Зарплата.Должность КАК Должность
ИЗ
    Справочник.Сотрудники КАК СправочникСотрудники
ЛЕВОЕ СОЕДИНЕНИЕ 
    РегистрСведений.Зарплата КАК Зарплата 
    ПО СправочникСотрудники.Ссылка = Зарплата.Сотрудник

Проблема заключается в следующем: если у пользователя в роли установлено право Чтение на регистр, но снято право Просмотр, колонки «Размер зарплаты» и «Должность» просто не отобразятся в таблице на форме. При этом программный запрос в модуле (например, созданный через Новый Запрос) отработает корректно и вернет данные. Почему же динамический список ведет себя иначе?

Дело в том, что Динамический список базируется на механизме Системы компоновки данных (СКД). Платформа 1С строго разделяет программный доступ к данным и их интерактивное отображение. Право Просмотр — это интерактивное право. Когда СКД готовит запрос к СУБД для отображения в интерфейсе, она анализирует права текущего пользователя. Если права на просмотр поля нет, СКД автоматически «вырезает» это поле из итогового текста запроса. В результате колонка не просто остается пустой — она физически удаляется из набора данных динамического списка.

Различие прав «Чтение» и «Просмотр»

Проанализируем детально, за что отвечают эти права, чтобы понимать логику работы платформы:

  1. Чтение (Read): Позволяет получать данные из базы программными средствами (запросы в коде, отчеты, работающие в привилегированном режиме). Это низкоуровневое разрешение на доступ к таблице БД.
  2. Просмотр (View): Позволяет видеть данные в визуальных компонентах: формах, списках, стандартных отчетах. Это «надстройка» над правом чтения, регулирующая видимость в интерфейсе.

Интересно ведет себя платформа со ссылочными типами. Если мы выводим поле Должность, которое является ссылкой на Справочник.Должности, и на этот справочник у нас есть только право Чтение, но на сам регистр зарплаты есть Просмотр — данные отобразятся. Платформа выведет Представление ссылки. Однако, если мы попытаемся через точку обратиться к реквизиту должности (например, Зарплата.Должность.Код), и на справочник должностей не будет права просмотра, поле окажется пустым.

Решение №1: Использование права «Просмотр» с ограничением форм

Это самый простой и эффективный способ, который мы рекомендуем использовать в большинстве случаев. Чтобы данные отобразились в списке, нам необходимо дать право Просмотр на регистр сведений. Но как при этом запретить пользователю открывать записи регистра или видеть его в списках?

Выполним следующие шаги:

  1. В роли пользователя установим галочки Чтение и Просмотр для нужного регистра.
  2. Чтобы пользователь не мог интерактивно «провалиться» в запись регистра, перейдем к правам самого объекта и снимем галочки у прав: Интерактивное открытие формы, Интерактивное добавление, Интерактивное редактирование.
  3. Если для регистра не созданы специфические формы, платформа не даст пользователю открыть стандартную форму записи, даже если он попытается сделать это через навигацию.

Таким образом, СКД получит разрешение на «вытягивание» данных для списка, но прямой интерактивный доступ к объекту останется закрытым.

Решение №2: Ограничение доступа на уровне записей (RLS)

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

Рассмотрим алгоритм настройки:

  1. Даем права Чтение и Просмотр.
  2. В настройках роли для регистра на закладке Ограничения доступа к данным добавляем условие на право Чтение.
  3. Прописываем условие. Если нужно, чтобы колонка была, но данные скрывались безусловно, можно использовать конструкцию ГДЕ ЛОЖЬ (хотя обычно используются условия по параметрам сеанса).

При использовании RLS колонка в динамическом списке останется доступной (пользователь сможет ее выбрать в настройках, применить отбор), но значения в строках будут отображаться как <Объект не найден> или просто пустые значения, если к конкретной записи нет доступа. Это более «профессиональный», но и более ресурсоемкий для системы путь.

Решение №3: Программное заполнение в событии ПриПолученииДанныхНаСервере

Если категорически нельзя давать право на просмотр, можно воспользоваться программным заполнением. Выясним, как это работает. Мы оставляем в запросе динамического списка только основные поля сотрудников. Для колонки с зарплатой создаем незаполненный реквизит в строке таблицы.

Разберем пример кода в модуле формы:


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

Важный нюанс: У этого метода есть существенные недостатки. Проанализируем их:

Подведение итогов и рекомендации

Проанализировав ситуацию, мы видим, что поведение платформы 1С логично: если пользователю запрещен «Просмотр» объекта, система оберегает его от любого визуального контакта с данными этого объекта, включая колонки в динамических списках.

Для решения задачи мы рекомендуем придерживаться следующей иерархии подходов:

  1. Основной вариант: Дать права Чтение + Просмотр, но заблокировать Интерактивное открытие формы и другие интерактивные действия. Это обеспечит работоспособность динамического списка и сохранит все возможности фильтрации и сортировки.
  2. Вариант для сложных условий: Использовать RLS, если нужно гибко управлять видимостью конкретных записей (например, «вижу свою зарплату, но не вижу чужую»).
  3. Крайний случай: Использовать ПриПолученииДанныхНаСервере, только если данные нужны исключительно «для справки» и по ним никогда не потребуется поиск или сортировка.

Помните, что безопасность данных в 1С — это комплекс мер. Ограничение прав на просмотр является лишь верхушкой айсберга, и правильное комбинирование интерактивных прав и прав на чтение данных позволяет создавать удобные и защищенные интерфейсы.

← На главную