При настройке системы ограничений доступа на уровне записей (Record Level Security или RLS) в типовых конфигурациях, таких как Управление торговлей 10.3, программисты часто сталкиваются с неприятным визуальным эффектом. В отчетах, например, по валовой прибыли или продажам, вместо ожидаемой фильтрации строк пользователь видит записи с надписью <Объект не найден> и длинным идентификатором в скобках. При этом суммы по таким «невидимым» документам всё равно учитываются в общих итогах отчета, что сводит на нет смысл самого ограничения доступа.
В данной статье мы подробно разберем, почему возникает эта проблема, как работает механизм РАЗРЕШЕННЫЕ в запросах и как правильно настроить роли, чтобы отчеты отображали только корректные данные без «битых» ссылок.
Для начала проанализируем ситуацию с точки зрения архитектуры базы данных 1С. Когда вы ограничиваете доступ к документу (например, Заказ покупателя), вы накладываете условие на чтение таблицы этого документа. Однако данные для отчетов (сумма выручки, себестоимость, количество) хранятся не в самих документах, а в регистрах накопления (например, Продажи, ПродажиСебестоимость).
Разберем механизм возникновения ошибки по шагам:
Регистратор, который является ссылкой на документ.<Объект не найден> (140:81f0...).Число 140 в скобках — это внутренний идентификатор типа объекта (TableID) в метаданных вашей базы. Оно подтверждает, что ссылка не является «битой» в плане целостности БД, она просто скрыта настройками безопасности.
Многие полагают, что добавление слова РАЗРЕШЕННЫЕ в текст запроса должно автоматически отсечь все недоступные данные. Рассмотрим, почему это не так. Оператор ВЫБРАТЬ РАЗРЕШЕННЫЕ инструктирует платформу выбирать только те записи из основной таблицы запроса, на которые у пользователя есть право Чтение.
Если запрос строится по регистру накопления Продажи, и на этот регистр в роли пользователя нет ограничений RLS, то запрос выберет абсолютно все записи. То обстоятельство, что поле Регистратор ссылается на запрещенный документ, не делает саму запись регистра «запрещенной». С точки зрения SQL-запроса, вы имеете полное право видеть запись регистра, но не имеете права «расшифровать» одну из её колонок.
Чтобы строки с недоступными документами полностью исчезли из отчета, а их суммы не влияли на итоги, необходимо наложить ограничение RLS непосредственно на те регистры накопления, которые используются в отчете. Рассмотрим, как это сделать на примере ограничения по полю Ответственный.
В конфигурации УТ 10.3 для этого нужно выполнить следующие действия:
Выясним, какие регистры являются источниками данных для вашего отчета. Для отчета «Валовая прибыль» это обычно:
ПродажиПродажиСебестоимостьОткроем нужную роль пользователя в Конфигураторе. Перейдем на вкладку «Права», выберем соответствующий регистр накопления и на праве Чтение нажмем кнопку изменения ограничения доступа.
Проблема в том, что в самих регистрах часто нет поля Ответственный. Оно есть в документе-регистраторе. Поэтому условие RLS должно обращаться к реквизитам регистратора. Рассмотрим пример кода ограничения:
ГДЕ Регистратор.Ответственный = &ТекущийПользователь
ИЛИ Регистратор.Ответственный ЕСТЬ NULL
В данном случае система при чтении каждой записи регистра будет проверять поле Ответственный в документе, который создал эту запись. Если ответственный совпадает с текущим пользователем, запись будет включена в выборку РАЗРЕШЕННЫЕ.
В типовых решениях 1С (особенно в УТ 10.3) ручное написание условий в каждом регистре — плохая практика. Проанализируем вкладку «Шаблоны ограничений» в окне настройки роли. Разработчики фирмы «1С» уже создали готовые механизмы, такие как #ОграничениеПоРегистратору.
Использование шаблона позволяет избежать ошибок и упрощает поддержку кода. Текст ограничения для регистра может выглядеть так:
#ПоРегистратору("Продажи")
Этот шаблон автоматически подставит необходимые условия проверки прав доступа к документу-регистратору. Если пользователю запрещено видеть документ, то и записи в регистре по этому документу будут для него скрыты.
Нужно учитывать, что проверка прав через Регистратор.Ответственный (обращение через точку) заставляет платформу выполнять LEFT JOIN с таблицами всех возможных документов-регистраторов на уровне SQL-сервера. Если регистр очень большой, это может привести к существенному замедлению формирования отчетов.
Проанализируем способы оптимизации:
Ответственный проиндексировано в документах.Ответственный и заполняют его при проведении. Тогда RLS будет работать мгновенно, обращаясь напрямую к физической таблице регистра без соединений.Мы выяснили причину появления надписи <Объект не найден>: это несоответствие прав доступа на документы и на записи регистров. Чтобы исправить это и обеспечить корректность итоговых сумм в отчетах, необходимо:
РАЗРЕШЕННЫЕ.После применения этих настроек строки с недоступными заказами исчезнут из отчета «Валовая прибыль», а пользователь увидит только те данные и суммы, за которые он несет ответственность.