Почему RLS в 1С по-разному работает для физических и виртуальных таблиц регистров накопления?

Программист 1С v8.3 (Обычные формы) 1С:Комплексная автоматизация IT и автоматизация бизнеса
← На главную

Разработка систем ограничения доступа на уровне записей (RLS) — одна из самых сложных задач в 1С:Предприятии 8. Часто программисты сталкиваются с ситуацией, когда запрос к физической таблице регистра накопления возвращает данные, а запрос к виртуальной таблице Обороты или ОстаткиИОбороты при тех же условиях возвращает пустой результат. Рассмотрим причины этого поведения, разберем технические нюансы работы платформы и выясним, как правильно отлаживать такие запросы.

Различие механизмов применения RLS к физическим и виртуальным таблицам

Для начала проанализируем ситуацию: почему платформа ведет себя неодинаково? Когда мы пишем запрос к физической таблице, условие RLS встраивается непосредственно в секцию WHERE (ГДЕ) результирующего SQL-запроса. Однако при обращении к виртуальным таблицам (например, РегистрНакопления.Взаиморасчеты.Обороты) платформа выполняет гораздо более сложную трансформацию.

Разберем основные факторы влияния:

  1. Трансляция макросов: В шаблонах ограничений часто используются макросы вида #Параметр(1). При обращении к физической таблице платформа четко сопоставляет параметры с имеющимися полями. В виртуальной таблице состав полей зависит от выбранных измерений и периодичности. Если в шаблоне RLS указано поле, которое не задействовано в параметрах или измерениях виртуальной таблицы, условие может отработать некорректно.
  2. Вложенные запросы: Платформа старается накладывать условия RLS внутри вложенного запроса, формирующего итоги виртуальной таблицы. Если условие содержит сложные соединения с регистрами сведений (как в типовых конфигурациях УПП или КА), оптимизатор SQL может построить неэффективный план или отсечь записи из-за наличия NULL в результатах соединений.
  3. Ключевое слово РАЗРЕШЕННЫЕ: Это критически важный момент. При работе с виртуальными таблицами использование ВЫБРАТЬ РАЗРЕШЕННЫЕ обязательно. Если к какой-то части данных, входящих в агрегат (сумму), у пользователя нет прав, платформа может вернуть пустой результат вместо частичных данных, чтобы исключить риск косвенного вычисления секретных показателей.

Анализ типового шаблона RLS

Рассмотрим пример сложного шаблона ограничения, который часто применяется в конфигурациях на обычных формах (УПП, КА). Проанализируем структуру запроса, накладываемого на право Чтение:


ГДЕ (&ИспользоватьОграниченияПравДоступаНаУровнеЗаписей = ЛОЖЬ
    ИЛИ (НЕ 1 В
        (ВЫБРАТЬ ПЕРВЫЕ 1
            1 КАК ПолеОтбора
        ИЗ
            РегистрСведений.НазначениеВидовОбъектовДоступа КАК НазначениеВидовОбъектовДоступа
        ГДЕ
            НазначениеВидовОбъектовДоступа.ГруппаПользователей = ГруппыПользователей.ГруппаПользователей
            И ВЫБОР
                КОГДА НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации)
                    И ТекущаяТаблица.#Параметр(1) ССЫЛКА Справочник.Организации
                    И НЕ ТекущаяТаблица.#Параметр(1) = ЗНАЧЕНИЕ(Справочник.Организации.ПустаяСсылка)
                ТОГДА ВЫБОР
                        КОГДА 1 В
                            (ВЫБРАТЬ ПЕРВЫЕ 1 1 ИЗ РегистрСведений.НастройкиПравДоступаПользователей КАК Настройки
                             ГДЕ Настройки.ОбъектДоступа = ТекущаяТаблица.#Параметр(1)
                             И Настройки.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации))
                        ТОГДА ИСТИНА ИНАЧЕ ЛОЖЬ КОНЕЦ
                ...
            КОНЕЦ = ЛОЖЬ))

В данном коде используется параметр сеанса &ИспользоватьОграниченияПравДоступаНаУровнеЗаписей. Если этот параметр по какой-то причине инициализирован неверно (например, при сбое при старте системы), всё условие может схлопнуться в ЛОЖЬ. Также обратим внимание на ТекущаяТаблица.#Параметр(2). Если этот параметр ссылается на измерение "Контрагент", а в запросе к виртуальной таблице оборотов контрагент не выбран или не задан в фильтрах, платформа может не найти связку для применения условия.

Проблема кэширования метаданных и параметров сеанса

Выясним причину, по которой иногда помогает "простое пересохранение" RLS или перезаход в программу. Платформа 1С активно кэширует скомпилированные условия доступа для каждой роли пользователя. Это необходимо для обеспечения высокой производительности при массовых запросах.

Рассмотрим шаги, которые могут привести к "глюку" и его устранению:

  1. Вы вносите изменения в права доступа или группы пользователей в режиме "1С:Предприятие".
  2. Платформа не успевает обновить кэш прав для текущего сеанса.
  3. При выполнении сложного запроса к виртуальной таблице система использует старые условия, которые входят в конфликт с новыми данными в регистрах сведений настроек прав.
  4. Перезапуск сеанса или пересохранение роли в Конфигураторе инициирует принудительное обновление кэша метаданных.

Практические рекомендации по отладке RLS

Если вы столкнулись с тем, что данные "исчезают" в виртуальных таблицах, выполните следующие действия:

1. Использование параметров виртуальной таблицы. Проанализируем типичную ошибку. Вместо использования секции ГДЕ после вызова таблицы, старайтесь передавать фильтры непосредственно в параметры виртуальной таблицы:


// Плохо (RLS может отработать после получения всех данных или некорректно)
ВЫБРАТЬ РАЗРЕШЕННЫЕ * ИЗ РегистрНакопления.Взаиморасчеты.Обороты() КАК Обороты ГДЕ Контрагент = &Контрагент

// Хорошо (RLS эффективнее накладывается на фильтрованные данные)
ВЫБРАТЬ РАЗРЕШЕННЫЕ * ИЗ РегистрНакопления.Взаиморасчеты.Обороты(,, , Контрагент = &Контрагент) КАК Обороты

2. Проверка пустых значений. В шаблонах RLS часто стоит проверка на пустую ссылку. Если в регистре накопления есть записи с незаполненными измерениями (например, пустая Организация), и RLS требует обязательного наличия прав на конкретную организацию, такие записи будут отсечены именно в виртуальных таблицах итогов.

3. Использование инструментов отладки. Для глубокого анализа рекомендуется использовать внешние инструменты, такие как "Инструменты разработчика" (ИР). В их составе есть "Редактор ограничения доступа", который позволяет:

4. Технологический журнал. В самых сложных случаях стоит настроить сбор Технологического журнала (ТЖ) с событием DBMSSQL. Вы сможете увидеть реальный SQL-запрос, отправляемый к СУБД. Ищите в тексте запроса конструкцию WHERE 1=0 — это верный признак того, что механизм RLS полностью заблокировал выборку из-за невыполнения условий.

Подведем итог: странное поведение RLS на виртуальных таблицах чаще всего связано либо с отсутствием ключевого слова РАЗРЕШЕННЫЕ, либо с тем, что динамически формируемые поля виртуальной таблицы не соответствуют ожиданиям шаблона RLS (макросов параметров). Всегда проверяйте актуальность кэша прав и используйте специализированные инструменты для "раскрытия" шаблонов в реальные запросы.

← На главную