Top.Mail.Ru
График: 5/2, full-time
Формат: удаленный/офис
Вакансия «1С-программист»

Как установить ограничения доступа на дополнительные реквизиты 1С без RLS

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

Постановка задачи

Есть дополнительные реквизиты, определенным пользователям необходимо ограничить к ним видимость в отчетах и динамических списках. Основное условие — не использовать RLS. Что такое дополнительные реквизиты в современных конфигурациях? Это записи в табличных частях по определенным свойствам, где свойства — это элементы плана видов характеристик «Дополнительные реквизиты и сведения».

Способы решения

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

Второй способ: попробуем оставить колонки, но не дадим посмотреть, что именно в них. Для этого решил в процедуру «ОбработкаПолученияПредставления» модуля менеджера ПВХ «Дополнительные реквизиты и сведения» добавить код, который по определенным условиям подменит представление для конкретного пользователя на «Эти данные вам не доступны!». Тут началась «магия».

Магия

Так сложилось, что для теста представление я подменил у булевого реквизита. В результате реквизит исчез как в выборе для отборов, так и в колонках динамических списков. Здорово, а что если во всех дополнительных реквизитах, которые не должны быть видимы представления, установить в «Неопределено»? Предположение сработало и для динамических списков, и для отчетов. Я не понимаю как это работает, что-то на уровне платформы — недокументированный функционал.

Реализация

В данной статье не буду рассматривать варианты сохранения информации. Рассмотрю основное — как реализовать отключение дополнительных реквизитов, чтобы работало быстро. Например, у нас есть процедура «ДополнительныеРеквизитыБезВидимости», которая по конкретному пользователю собирает массив с элементами типа «ПВХ. ДополнительныеРеквизитыИСведения», которые он не должен видеть. Если ее вызывать в «ОбработкаПолученияПредставления», то на каждую строчку будет отрабатывать этот алгоритм. Получается долго. Для скорости удобнее добавить новый параметр сеанса с типом «ФиксированноеСоответствие» и получать так данные.

Процедура ЗначениеПараметровСеансаДляНастроекДР(ИмяПараметра, УстановленныеПараметры) Экспорт
	
	НеОтображатьСоответствие = Новый Соответствие;

	НеОтображатьМассив = ДополнительныеРеквизитыБезВидимости();
	Для каждого Реквизит Из НеОтображатьМассив Цикл
		НеОтображатьСоответствие.Вставить(Реквизит, Истина);
	КонецЦикла;
	
	ПараметрыСеанса[ИмяПараметра] = Новый ФиксированноеСоответствие(НеОтображатьСоответствие);
		
КонецПроцедуры

Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
	
	ПредставлениеНабора = "";
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
	Если Не УправлениеСвойствамиПовтИсп.ЭтоОсновнойЯзык()
		И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Мультиязычность") Тогда
		МодульМультиязычностьКлиентСервер = ОбщегоНазначения.ОбщийМодуль("МультиязычностьКлиентСервер");
		МодульМультиязычностьКлиентСервер.ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка, "Заголовок");
	КонецЕсли;
	
	Если ЗначениеЗаполнено(Данные.НаборСвойств) Тогда
		ПредставленияНаборовСвойств = УправлениеСвойствамиПовтИсп.ПредставленияНаборовСвойств();
		ПредставлениеНабора = ПредставленияНаборовСвойств.Получить(Данные.НаборСвойств);
	КонецЕсли;
#Иначе
	Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.Мультиязычность") Тогда
		МодульМультиязычностьКлиентСервер = ОбщегоНазначенияКлиент.ОбщийМодуль("МультиязычностьКлиентСервер");
		МодульМультиязычностьКлиентСервер.ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка, "Заголовок");
	КонецЕсли;
#КонецЕсли
	
	Если Не ЗначениеЗаполнено(Представление) Тогда
		Представление = Данные.Заголовок;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(Данные.НаборСвойств) Тогда
		Если Не ЗначениеЗаполнено(ПредставлениеНабора) Тогда
			ПредставлениеНабора = Строка(Данные.НаборСвойств);
		КонецЕсли;
		Представление = Представление + " (" + ПредставлениеНабора + ")";
	КонецЕсли;
	// ++ ProSto Журавлев
	НеОтображать = ПараметрыСеанса.МОЙ_ДополнительныеРеквизитыБезВидимости;
	Если НеОтображать.Получить(Данные.Ссылка) = Истина Тогда
		Представление = Неопределено;
	КонецЕсли;
	// -- ProSto Журавлев
	СтандартнаяОбработка = Ложь;
КонецПроцедуры

Comments

So empty here ... leave a comment!

Добавить комментарий

Sidebar