В практике разработки на платформе 1С:Предприятие 8.3 часто возникает ситуация, когда необходимо вывести дополнительные данные в список (например, в форму списка справочника), но при этом нужно ограничить прямой доступ пользователя к источнику этих данных. Типичный пример: отображение текущей зарплаты или должности из регистра сведений в списке сотрудников. Разберем, почему колонки могут «магическим образом» исчезать и как правильно настроить права доступа, чтобы интерфейс оставался информативным, но безопасным.
Рассмотрим типичную конфигурацию. У нас есть справочник Справочник.Сотрудники и регистр сведений РегистрСведений.Зарплата. В динамическом списке справочника прописан запрос с левым соединением:
ВЫБРАТЬ
СправочникСотрудники.Ссылка КАК Ссылка,
СправочникСотрудники.Код КАК Код,
СправочникСотрудники.Наименование КАК Наименование,
Зарплата.РазмерЗарплаты КАК РазмерЗарплаты,
Зарплата.Должность КАК Должность
ИЗ
Справочник.Сотрудники КАК СправочникСотрудники
ЛЕВОЕ СОЕДИНЕНИЕ
РегистрСведений.Зарплата КАК Зарплата
ПО СправочникСотрудники.Ссылка = Зарплата.Сотрудник
Проблема заключается в следующем: если у пользователя в роли установлено право Чтение на регистр, но снято право Просмотр, колонки «Размер зарплаты» и «Должность» просто не отобразятся в таблице на форме. При этом программный запрос в модуле (например, созданный через Новый Запрос) отработает корректно и вернет данные. Почему же динамический список ведет себя иначе?
Дело в том, что Динамический список базируется на механизме Системы компоновки данных (СКД). Платформа 1С строго разделяет программный доступ к данным и их интерактивное отображение. Право Просмотр — это интерактивное право. Когда СКД готовит запрос к СУБД для отображения в интерфейсе, она анализирует права текущего пользователя. Если права на просмотр поля нет, СКД автоматически «вырезает» это поле из итогового текста запроса. В результате колонка не просто остается пустой — она физически удаляется из набора данных динамического списка.
Проанализируем детально, за что отвечают эти права, чтобы понимать логику работы платформы:
Интересно ведет себя платформа со ссылочными типами. Если мы выводим поле Должность, которое является ссылкой на Справочник.Должности, и на этот справочник у нас есть только право Чтение, но на сам регистр зарплаты есть Просмотр — данные отобразятся. Платформа выведет Представление ссылки. Однако, если мы попытаемся через точку обратиться к реквизиту должности (например, Зарплата.Должность.Код), и на справочник должностей не будет права просмотра, поле окажется пустым.
Это самый простой и эффективный способ, который мы рекомендуем использовать в большинстве случаев. Чтобы данные отобразились в списке, нам необходимо дать право Просмотр на регистр сведений. Но как при этом запретить пользователю открывать записи регистра или видеть его в списках?
Выполним следующие шаги:
Таким образом, СКД получит разрешение на «вытягивание» данных для списка, но прямой интерактивный доступ к объекту останется закрытым.
Если задача стоит более жестко — например, нужно показывать зарплату только по определенным подразделениям или скрывать данные полностью, но сохранить колонку в интерфейсе — следует рассмотреть RLS (Record Level Security).
Рассмотрим алгоритм настройки:
ГДЕ ЛОЖЬ (хотя обычно используются условия по параметрам сеанса).При использовании RLS колонка в динамическом списке останется доступной (пользователь сможет ее выбрать в настройках, применить отбор), но значения в строках будут отображаться как <Объект не найден> или просто пустые значения, если к конкретной записи нет доступа. Это более «профессиональный», но и более ресурсоемкий для системы путь.
Если категорически нельзя давать право на просмотр, можно воспользоваться программным заполнением. Выясним, как это работает. Мы оставляем в запросе динамического списка только основные поля сотрудников. Для колонки с зарплатой создаем незаполненный реквизит в строке таблицы.
Разберем пример кода в модуле формы:
&НаСервере
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
// Собираем ссылки на сотрудников из текущих строк списка
МассивСсылок = Строки.ПолучитьКлючи();
// Выполняем запрос к регистру (права на Чтение у пользователя есть)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Зарплата.Сотрудник КАК Сотрудник,
| Зарплата.РазмерЗарплаты КАК РазмерЗарплаты
|ИЗ
| РегистрСведений.Зарплата КАК Зарплата
|ГДЕ
| Зарплата.Сотрудник В(&МассивСсылок)";
Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);
Результат = Запрос.Выполнить().Выбрать();
// Заполняем колонки в отображаемых строках
Пока Результат.Следующий() Цикл
СтруктураДанных = Строки[Результат.Сотрудник];
СтруктураДанных.Данные["РазмерЗарплаты"] = Результат.РазмерЗарплаты;
КонецЦикла;
КонецПроцедуры
Важный нюанс: У этого метода есть существенные недостатки. Проанализируем их:
Проанализировав ситуацию, мы видим, что поведение платформы 1С логично: если пользователю запрещен «Просмотр» объекта, система оберегает его от любого визуального контакта с данными этого объекта, включая колонки в динамических списках.
Для решения задачи мы рекомендуем придерживаться следующей иерархии подходов:
ПриПолученииДанныхНаСервере, только если данные нужны исключительно «для справки» и по ним никогда не потребуется поиск или сортировка.Помните, что безопасность данных в 1С — это комплекс мер. Ограничение прав на просмотр является лишь верхушкой айсберга, и правильное комбинирование интерактивных прав и прав на чтение данных позволяет создавать удобные и защищенные интерфейсы.