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