Почему конструкция ВЫБРАТЬ РАЗРЕШЕННЫЕ возвращает «Объект не найден» и как это исправить?

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

При работе с механизмом ограничения доступа на уровне записей (RLS) в 1С:Предприятии программисты часто сталкиваются с ситуацией, когда запрос с использованием ключевого слова ВЫБРАТЬ РАЗРЕШЕННЫЕ возвращает в результате ссылки с представлением «Объект не найден». Это вызывает недоумение: если данные запрещены, почему они вообще попали в выборку? Давайте подробно разберем причины такого поведения платформы и рассмотрим способы решения этой проблемы.

Суть проблемы: почему РАЗРЕШЕННЫЕ «пропускает» лишнее

Рассмотрим ситуацию: вы выполняете запрос к регистру сведений, выбирая из него ссылки на договоры или организации. Несмотря на то, что на справочник «Организации» наложен RLS по значению, в итоговой таблице вы видите идентификаторы (GUID) или надписи <Объект не найден>. Проанализируем, почему это происходит.

Основная причина заключается в том, что ключевое слово ВЫБРАТЬ РАЗРЕШЕННЫЕ действует только на те таблицы, которые непосредственно указаны в секции ИЗ вашего запроса. Если вы выбираете данные из регистра сведений, платформа проверяет права доступа именно к записям этого регистра. Если на сам регистр RLS не настроен, запрос успешно выберет все записи, включая ссылки на объекты (договоры, контрагенты), к которым у пользователя может не быть доступа.

Когда платформа пытается вывести результат пользователю, она хочет сформировать «представление» ссылки (обычно это Наименование или Код). В этот момент система обращается к полям объекта, на которые у пользователя прав уже нет. В итоге вместо имени вы видите «Объект не найден».

Разбор по шагам: влияние настроек RLS на поле Ссылка

Выясним причину, скрытую в настройках ролей. В системе 1С права на поля объекта могут быть разделены. Рассмотрим стандартную ситуацию настройки RLS для справочника:

  1. Для поля Ссылка ограничение не установлено (пустая строка в условии RLS).
  2. Для группы «Прочие поля» установлено ограничение (например, фильтр по организации).

В этом случае, когда выполняется запрос ВЫБРАТЬ РАЗРЕШЕННЫЕ Ссылка ИЗ Справочник.Организации, платформа видит, что на поле Ссылка ограничений нет, и включает все записи в результат. Однако, как только вы попытаетесь получить любое другое поле (Наименование, ИНН) или просто вывести ссылку в форму (где потребуется ее представление), сработает ограничение на «Прочие поля». Данные не будут получены, и система выдаст GUID или сообщение о битой ссылке.

Решение №1: Использование соединения с основной таблицей

Самый надежный способ отсечь запрещенные записи в запросе — это принудительно соединить таблицу данных (например, регистр) с таблицей объекта, на который наложен RLS. Разберем на примере запроса к регистру АрендуемыеПлощади:


ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ
    АрендуемыеПлощадиСрезПоследних.ДоговорКонтрагента КАК ДоговорКонтрагента
ПОМЕСТИТЬ СписокДоговоров
ИЗ
    РегистрСведений.АрендуемыеПлощади.СрезПоследних(&Период, ) КАК АрендуемыеПлощадиСрезПоследних
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов
        ПО АрендуемыеПлощадиСрезПоследних.ДоговорКонтрагента = ДоговорыКонтрагентов.Ссылка
ИНДЕКСИРОВАТЬ ПО
    ДоговорКонтрагента

Что здесь произошло? Благодаря использованию ВНУТРЕННЕЕ СОЕДИНЕНИЕ со справочником, на который наложены ограничения RLS, конструкция ВЫБРАТЬ РАЗРЕШЕННЫЕ применит фильтры обеих таблиц. Если у пользователя нет прав на конкретный договор, запись из справочника не будет выбрана, и ВНУТРЕННЕЕ СОЕДИНЕНИЕ исключит соответствующую строку из регистра из итогового результата.

Решение №2: Настройка RLS на поля ссылок в регистрах

Проанализируем ситуацию с другой стороны. Если бизнес-логика подразумевает, что пользователь не должен видеть записи регистра, относящиеся к чужим организациям, то правильным решением будет настройка RLS непосредственно на таблицу регистра.

Вам необходимо зайти в роль пользователя и для регистра сведений (или накопления) прописать условие чтения. Например:

ДоговорКонтрагента.Организация В (&СписокРазрешенныхОрганизаций)

В этом случае запрос к регистру с использованием РАЗРЕШЕННЫЕ сразу отфильтрует ненужные записи без необходимости делать дополнительные соединения.

Важный нюанс: ошибка «Нет прав на работу с таблицей»

Иногда программисты сталкиваются с тем, что даже при наличии слова РАЗРЕШЕННЫЕ метод Запрос.Выполнить() вызывает исключение. Рассмотрим, почему это происходит.

Важно различать базовое право «Чтение» на уровне метаданных и ограничение RLS на уровне записей:

  1. Если у пользователя в роли вообще снята галочка «Чтение» на объект (таблицу), то ключевое слово РАЗРЕШЕННЫЕ не поможет — запрос упадет с ошибкой.
  2. Если право на «Чтение» есть, но настроены условия RLS, то запрос не упадет, а просто вернет только те записи, которые удовлетворяют условию.

Поэтому всегда проверяйте, есть ли у пользователя базовый доступ к таблице, прежде чем использовать её в запросе под обычными правами.

Особенности работы во временных таблицах

Посмотрим на типичную ошибку при работе с временными таблицами. Ключевое слово РАЗРЕШЕННЫЕ игнорируется платформой при выборке из уже созданной временной таблицы. Рассмотрим пример:


// Шаг 1: Помещаем данные во временную таблицу (например, в привилегированном модуле)
МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос1 = Новый Запрос("ВЫБРАТЬ * ПОМЕСТИТЬ ВТ_Данные ИЗ РегистрСведений.Цены");
Запрос1.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос1.Выполнить();

// Шаг 2: Выбираем данные под обычным пользователем
Запрос2 = Новый Запрос("ВЫБРАТЬ РАЗРЕШЕННЫЕ * ИЗ ВТ_Данные");
Запрос2.МенеджерВременныхТаблиц = МенеджерВТ;
Результат = Запрос2.Выполнить(); // RLS НЕ СРАБОТАЕТ

Поскольку ВТ_Данные не является физической таблицей базы данных, механизм RLS на неё не распространяется. Ограничение прав должно быть обеспечено в момент наполнения временной таблицы (в первом запросе).

Влияние на производительность

Использование ВЫБРАТЬ РАЗРЕШЕННЫЕ добавляет к вашему SQL-запросу внушительный кусок кода с подзапросами и проверками прав. Рассмотрим рекомендации по оптимизации:

Итоги и рекомендации

Мы проанализировали ситуацию и выяснили, что появление «битых ссылок» — это не ошибка платформы, а следствие гибкости настроек доступа. Чтобы ваши отчеты и обработки работали корректно, следуйте этим правилам:

  1. Если вам нужно исключить записи с «Объект не найден», делайте ВНУТРЕННЕЕ СОЕДИНЕНИЕ с основной таблицей справочника.
  2. Проверяйте, чтобы RLS был настроен не только на справочники, но и на связанные регистры, если данные из них выбираются напрямую.
  3. Помните, что обращение «через точку» (например, Договор.Организация) в условиях запроса с RLS может вернуть NULL для запрещенных объектов, что также отфильтрует записи.
  4. Следите за тем, чтобы у пользователя было право на «Чтение» объекта на уровне метаданных, иначе РАЗРЕШЕННЫЕ не предотвратит аварийное завершение запроса.

Соблюдение этих принципов позволит создавать надежные и быстрые системы с разграничением прав доступа, в которых пользователи будут видеть только ту информацию, которая им действительно полагается.

← На главную