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