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