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