В процессе разработки и сопровождения сложных отчетов на базе Системы компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда под полными правами отчет выглядит идеально, а у рядового пользователя в окне настроек пропадает большая часть доступных полей. Это происходит из-за того, что платформа 1С автоматически фильтрует доступные настройки компоновщика, основываясь на правах текущего пользователя к объектам метаданных, используемым в запросе.
Рассмотрим ситуацию подробнее: отчет должен формироваться в привилегированном режиме, чтобы пользователь мог видеть итоговые цифры, но при этом ему нужно предоставить возможность самостоятельно выбирать группировки или настраивать отборы по полям, на которые у него нет прямого права «Просмотр». Разберем по шагам, почему старые методы перестают работать и какие современные способы решения существуют.
Раньше многие разработчики использовали простой прием в модуле формы отчета: принудительную инициализацию КомпоновщикаНастроек в процедуре ПередЗагрузкойПользовательскихНастроекНаСервере. Код выглядел примерно так:
&НаСервере
Процедура ПередЗагрузкойПользовательскихНастроекНаСервере(Настройки, ИспользуютсяСтандартныеНастройки)
УстановитьПривилегированныйРежим(Истина);
ОтчетОбр = РеквизитФормыВЗначение("Отчет");
ОсновнаяСКД = ОтчетОбр.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Отчет.КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(ОсновнаяСКД));
КонецПроцедуры
Однако в последних версиях платформы 8.3.15 и выше этот механизм стал работать нестабильно. Дело в том, что после выполнения серверного кода управление возвращается на клиента, где форма производит повторную проверку состава доступных полей. Если платформа видит, что ИсточникДоступныхНастроекКомпоновкиДанных связан напрямую с объектом метаданных (схемой внутри отчета), она применяет ограничения прав текущего сеанса, «обрезая» все лишнее.
Один из самых эффективных способов обойти проверку прав на клиенте — это инициализировать источник настроек не через сам объект схемы, а через его адрес во временном хранилище. Для платформы схема, полученная по строковому адресу, считается «внешним» ресурсом, и механизмы автоматического скрытия полей отрабатывают иначе.
Проанализируем алгоритм реализации этого метода:
ПриСозданииНаСервере поместим схему компоновки во временное хранилище.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Получаем схему
Схема = Отчеты.НашОтчет.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
// Помещаем во временное хранилище с привязкой к идентификатору формы
АдресСхемы = ПоместитьВоВременноеХранилище(Схема, УникальныйИдентификатор);
// Создаем источник настроек по адресу
ИсточникНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(АдресСхемы);
// Инициализируем компоновщик
Отчет.КомпоновщикНастроек.Инициализировать(ИсточникНастроек);
КонецПроцедуры
Этот метод заставляет систему доверять составу полей, так как на момент отрисовки настроек на клиенте связь с конкретными правами на справочники или документы становится менее «жесткой» для механизмов отрисовки интерфейса.
Выясним причину, по которой поля исчезают на уровне метаданных. В 1С права «Чтение» и «Просмотр» — это разные сущности. Если у пользователя нет права «Просмотр» на реквизит справочника, он никогда не увидит его в СКД, даже если отчет работает в привилегированном режиме.
Рассмотрим стратегию настройки ролей:
ПривилегированныйРежимПриУстановкеПараметров или выполняйте запрос в привилегированном модуле.Таким образом, пользователь сможет выбирать поля в настройках (так как есть право на просмотр структуры), но не сможет получить данные из этих полей через обычные списки или консоль запросов (так как RLS ограничит чтение записей).
В конфигурациях УТ 11, ERP 2 или КА 2 часто используется метод подмены текста запроса. Это самый трудозатратный, но и самый надежный способ, гарантирующий работу независимо от обновлений платформы.
Суть метода заключается в следующем:
ВЫБРАТЬ 1 КАК Поле1. При этом вручную создаются все необходимые поля на закладке «Наборы данных» с нужными типами.Проанализируем пример кода в модуле объекта отчета:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
УстановитьПривилегированныйРежим(Истина);
// Получаем реальный текст запроса
ТекстРеальногоЗапроса = "ВЫБРАТЬ Продажи.Сумма, Продажи.Контрагент ИЗ РегистрНакопления.Продажи КАК Продажи";
// Подменяем текст в схеме
СхемаКомпоновки = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
СхемаКомпоновки.НаборыДанных.НаборДанных1.Запрос = ТекстРеальногоЗапроса;
// Дальнейшая стандартная компоновка
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры
Если поля все равно не появляются, стоит обратить внимание на следующие настройки в самой СКД:
Отчет.КомпоновщикНастроек.ОбновитьСоставДоступныхНастроек(). Это принудительно обновляет дерево доступных полей перед передачей формы на клиент.Важный момент: если ваш отчет находится в расширении, обязательно проверьте настройки прав в самом расширении. Часто разработчики забывают добавить нужные объекты в роли расширения, из-за чего СКД внутри расширения не видит метаданные основной конфигурации, даже если у пользователя есть полные права на основную базу.
Подводя итог, можно сказать, что наиболее стабильным решением для современных версий 1С является использование URL-адреса схемы во временном хранилище. Это позволяет сохранить структуру отчета в конфигураторе и при этом обеспечить пользователям гибкость настроек без изменения глобальных прав доступа.