Разработка систем ограничения доступа на уровне записей (RLS) — одна из самых сложных задач в 1С:Предприятии 8. Часто программисты сталкиваются с ситуацией, когда запрос к физической таблице регистра накопления возвращает данные, а запрос к виртуальной таблице Обороты или ОстаткиИОбороты при тех же условиях возвращает пустой результат. Рассмотрим причины этого поведения, разберем технические нюансы работы платформы и выясним, как правильно отлаживать такие запросы.
Для начала проанализируем ситуацию: почему платформа ведет себя неодинаково? Когда мы пишем запрос к физической таблице, условие RLS встраивается непосредственно в секцию WHERE (ГДЕ) результирующего SQL-запроса. Однако при обращении к виртуальным таблицам (например, РегистрНакопления.Взаиморасчеты.Обороты) платформа выполняет гораздо более сложную трансформацию.
Разберем основные факторы влияния:
#Параметр(1). При обращении к физической таблице платформа четко сопоставляет параметры с имеющимися полями. В виртуальной таблице состав полей зависит от выбранных измерений и периодичности. Если в шаблоне RLS указано поле, которое не задействовано в параметрах или измерениях виртуальной таблицы, условие может отработать некорректно.NULL в результатах соединений.ВЫБРАТЬ РАЗРЕШЕННЫЕ обязательно. Если к какой-то части данных, входящих в агрегат (сумму), у пользователя нет прав, платформа может вернуть пустой результат вместо частичных данных, чтобы исключить риск косвенного вычисления секретных показателей.Рассмотрим пример сложного шаблона ограничения, который часто применяется в конфигурациях на обычных формах (УПП, КА). Проанализируем структуру запроса, накладываемого на право Чтение:
ГДЕ (&ИспользоватьОграниченияПравДоступаНаУровнеЗаписей = ЛОЖЬ
ИЛИ (НЕ 1 В
(ВЫБРАТЬ ПЕРВЫЕ 1
1 КАК ПолеОтбора
ИЗ
РегистрСведений.НазначениеВидовОбъектовДоступа КАК НазначениеВидовОбъектовДоступа
ГДЕ
НазначениеВидовОбъектовДоступа.ГруппаПользователей = ГруппыПользователей.ГруппаПользователей
И ВЫБОР
КОГДА НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации)
И ТекущаяТаблица.#Параметр(1) ССЫЛКА Справочник.Организации
И НЕ ТекущаяТаблица.#Параметр(1) = ЗНАЧЕНИЕ(Справочник.Организации.ПустаяСсылка)
ТОГДА ВЫБОР
КОГДА 1 В
(ВЫБРАТЬ ПЕРВЫЕ 1 1 ИЗ РегистрСведений.НастройкиПравДоступаПользователей КАК Настройки
ГДЕ Настройки.ОбъектДоступа = ТекущаяТаблица.#Параметр(1)
И Настройки.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации))
ТОГДА ИСТИНА ИНАЧЕ ЛОЖЬ КОНЕЦ
...
КОНЕЦ = ЛОЖЬ))
В данном коде используется параметр сеанса &ИспользоватьОграниченияПравДоступаНаУровнеЗаписей. Если этот параметр по какой-то причине инициализирован неверно (например, при сбое при старте системы), всё условие может схлопнуться в ЛОЖЬ. Также обратим внимание на ТекущаяТаблица.#Параметр(2). Если этот параметр ссылается на измерение "Контрагент", а в запросе к виртуальной таблице оборотов контрагент не выбран или не задан в фильтрах, платформа может не найти связку для применения условия.
Выясним причину, по которой иногда помогает "простое пересохранение" RLS или перезаход в программу. Платформа 1С активно кэширует скомпилированные условия доступа для каждой роли пользователя. Это необходимо для обеспечения высокой производительности при массовых запросах.
Рассмотрим шаги, которые могут привести к "глюку" и его устранению:
Если вы столкнулись с тем, что данные "исчезают" в виртуальных таблицах, выполните следующие действия:
1. Использование параметров виртуальной таблицы. Проанализируем типичную ошибку. Вместо использования секции ГДЕ после вызова таблицы, старайтесь передавать фильтры непосредственно в параметры виртуальной таблицы:
// Плохо (RLS может отработать после получения всех данных или некорректно)
ВЫБРАТЬ РАЗРЕШЕННЫЕ * ИЗ РегистрНакопления.Взаиморасчеты.Обороты() КАК Обороты ГДЕ Контрагент = &Контрагент
// Хорошо (RLS эффективнее накладывается на фильтрованные данные)
ВЫБРАТЬ РАЗРЕШЕННЫЕ * ИЗ РегистрНакопления.Взаиморасчеты.Обороты(,, , Контрагент = &Контрагент) КАК Обороты
2. Проверка пустых значений. В шаблонах RLS часто стоит проверка на пустую ссылку. Если в регистре накопления есть записи с незаполненными измерениями (например, пустая Организация), и RLS требует обязательного наличия прав на конкретную организацию, такие записи будут отсечены именно в виртуальных таблицах итогов.
3. Использование инструментов отладки. Для глубокого анализа рекомендуется использовать внешние инструменты, такие как "Инструменты разработчика" (ИР). В их составе есть "Редактор ограничения доступа", который позволяет:
4. Технологический журнал. В самых сложных случаях стоит настроить сбор Технологического журнала (ТЖ) с событием DBMSSQL. Вы сможете увидеть реальный SQL-запрос, отправляемый к СУБД. Ищите в тексте запроса конструкцию WHERE 1=0 — это верный признак того, что механизм RLS полностью заблокировал выборку из-за невыполнения условий.
Подведем итог: странное поведение RLS на виртуальных таблицах чаще всего связано либо с отсутствием ключевого слова РАЗРЕШЕННЫЕ, либо с тем, что динамически формируемые поля виртуальной таблицы не соответствуют ожиданиям шаблона RLS (макросов параметров). Всегда проверяйте актуальность кэша прав и используйте специализированные инструменты для "раскрытия" шаблонов в реальные запросы.