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