Как установить ограничения доступа на дополнительные реквизиты 1С без RLS
Вот уже 20 лет в 1С я сталкиваюсь со странными ситуациями, каждый раз находится логическое объяснение. Магии не существует, но я впервые решил задачу по дополнительным реквизитам 1С и не понимаю, как это работает. Спойлер: недокументированные возможности платформы, не «магия».
Постановка задачи
Есть дополнительные реквизиты, определенным пользователям необходимо ограничить к ним видимость в отчетах и динамических списках. Основное условие — не использовать RLS. Что такое дополнительные реквизиты в современных конфигурациях? Это записи в табличных частях по определенным свойствам, где свойства — это элементы плана видов характеристик «Дополнительные реквизиты и сведения».
Способы решения
Первая мысль была попробовать использовать функциональные опции (далее ФО). Не сработало: ФО накладываются на объекты метаданных, а у нас конкретные записи в табличной части.
Второй способ: попробуем оставить колонки, но не дадим посмотреть, что именно в них. Для этого решил в процедуру «ОбработкаПолученияПредставления» модуля менеджера ПВХ «Дополнительные реквизиты и сведения» добавить код, который по определенным условиям подменит представление для конкретного пользователя на «Эти данные вам не доступны!». Тут началась «магия».
Магия
Так сложилось, что для теста представление я подменил у булевого реквизита. В результате реквизит исчез как в выборе для отборов, так и в колонках динамических списков. Здорово, а что если во всех дополнительных реквизитах, которые не должны быть видимы представления, установить в «Неопределено»? Предположение сработало и для динамических списков, и для отчетов. Я не понимаю как это работает, что-то на уровне платформы — недокументированный функционал.
Реализация
В данной статье не буду рассматривать варианты сохранения информации. Рассмотрю основное — как реализовать отключение дополнительных реквизитов, чтобы работало быстро. Например, у нас есть процедура «ДополнительныеРеквизитыБезВидимости», которая по конкретному пользователю собирает массив с элементами типа «ПВХ. ДополнительныеРеквизитыИСведения», которые он не должен видеть. Если ее вызывать в «ОбработкаПолученияПредставления», то на каждую строчку будет отрабатывать этот алгоритм. Получается долго. Для скорости удобнее добавить новый параметр сеанса с типом «ФиксированноеСоответствие» и получать так данные.
Процедура ЗначениеПараметровСеансаДляНастроекДР(ИмяПараметра, УстановленныеПараметры) Экспорт
НеОтображатьСоответствие = Новый Соответствие;
НеОтображатьМассив = ДополнительныеРеквизитыБезВидимости();
Для каждого Реквизит Из НеОтображатьМассив Цикл
НеОтображатьСоответствие.Вставить(Реквизит, Истина);
КонецЦикла;
ПараметрыСеанса[ИмяПараметра] = Новый ФиксированноеСоответствие(НеОтображатьСоответствие);
КонецПроцедуры
Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
ПредставлениеНабора = "";
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
Если Не УправлениеСвойствамиПовтИсп.ЭтоОсновнойЯзык()
И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Мультиязычность") Тогда
МодульМультиязычностьКлиентСервер = ОбщегоНазначения.ОбщийМодуль("МультиязычностьКлиентСервер");
МодульМультиязычностьКлиентСервер.ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка, "Заголовок");
КонецЕсли;
Если ЗначениеЗаполнено(Данные.НаборСвойств) Тогда
ПредставленияНаборовСвойств = УправлениеСвойствамиПовтИсп.ПредставленияНаборовСвойств();
ПредставлениеНабора = ПредставленияНаборовСвойств.Получить(Данные.НаборСвойств);
КонецЕсли;
#Иначе
Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.Мультиязычность") Тогда
МодульМультиязычностьКлиентСервер = ОбщегоНазначенияКлиент.ОбщийМодуль("МультиязычностьКлиентСервер");
МодульМультиязычностьКлиентСервер.ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка, "Заголовок");
КонецЕсли;
#КонецЕсли
Если Не ЗначениеЗаполнено(Представление) Тогда
Представление = Данные.Заголовок;
КонецЕсли;
Если ЗначениеЗаполнено(Данные.НаборСвойств) Тогда
Если Не ЗначениеЗаполнено(ПредставлениеНабора) Тогда
ПредставлениеНабора = Строка(Данные.НаборСвойств);
КонецЕсли;
Представление = Представление + " (" + ПредставлениеНабора + ")";
КонецЕсли;
// ++ ProSto Журавлев
НеОтображать = ПараметрыСеанса.МОЙ_ДополнительныеРеквизитыБезВидимости;
Если НеОтображать.Получить(Данные.Ссылка) = Истина Тогда
Представление = Неопределено;
КонецЕсли;
// -- ProSto Журавлев
СтандартнаяОбработка = Ложь;
КонецПроцедуры
Comments
So empty here ... leave a comment!