Почему при ограничении доступа RLS в документах 1С появляется «Объект не найден» и как это исправить?

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

При внедрении ограничений на уровне записей (RLS) для справочника Сотрудники разработчики часто сталкиваются с неприятной ситуацией: если сотрудник из недоступного пользователю подразделения попадает в документ (например, в ТабельУчетаРабочегоВремени через внешнюю загрузку или по совместительству), пользователь видит вместо его ФИО системную заглушку «<Объект не найден [УИД]>».

Разберем детально механизм возникновения этой проблемы в платформе 1С:Предприятие 8, а также рассмотрим архитектурно правильные способы ее решения без потери производительности базы данных.

Причина появления «Объект не найден»

Проанализируем, как платформа 1С отображает ссылочные данные в формах и списках. Когда в роли для права Чтение задается единое общее условие RLS на всю таблицу справочника (без детализации по конкретным полям), платформа блокирует доступ к записи целиком.

Это означает, что для пользователя становятся недоступными не только реквизиты объекта, но и его ссылка, код и наименование. При открытии документа платформа пытается получить строковое представление ссылки из табличной части, однако СУБД возвращает пустой результат из-за наложенного ограничения RLS. В результате интерфейс платформы отображает строку «<Объект не найден>».

Решение 1. Ограничение доступа на уровне полей (Field-level RLS)

Самый эффективный и правильный способ в рамках собственной настройки RLS — разделить право на чтение полей представления и остальных реквизитов объекта.

Выполним настройку роли в конфигураторе по следующим шагам:

  1. Открываем нужную роль и переходим к справочнику Сотрудники на вкладку Ограничение доступа к данным для права Чтение.
  2. Создаем две отдельные строки ограничений:
    1. Для полей представления: выбираем поля Ссылка, Наименование (или ФИО), Код. Для этой строки условие ограничения оставляем пустым или указываем ГДЕ ИСТИНА. Это дает платформе возможность считывать ссылки и выводить наименования сотрудников во всех документах, отчетах и списках без ошибок.
    2. Для прочих полей: выбираем пункт <Прочие поля>. Здесь прописываем рабочее условие ограничения по подразделению (например, через параметры сеанса).
  3. Для права Изменение задаем условие целиком на всю запись, чтобы пользователь не мог модифицировать данные сотрудников чужого подразделения.

Посмотрим на пример логики условия для поля <Прочие поля>:

ГДЕ ТекущаяТаблица.ГоловноеПодразделение В (&ДоступныеПодразделения)

При такой схеме пользователь видит ФИО сотрудника в табличной части документа, однако при попытке открыть форму самого элемента справочника платформа корректно сообщит о нарушении прав доступа, так как закрыт доступ к основным реквизитам объекта.

Решение 2. Использование типовых механизмов БСП и ЗУП

В типовых конфигурациях (включая 1С:ЗУП редакции 3) прямой код RLS в ролях практически не разрабатывается вручную с нуля. Вместо этого применяется механизм управления доступом на базе Библиотеки стандартных подсистем (БСП) в производительном режиме.

В типовой подсистеме доступ рассчитывается через регистры сведений КлючиДоступаКОбъектам и КлючиДоступаПользователей с использованием шаблонов ПоЗначениям и ПоЗначениямРасширенный. В этих шаблонах уже на уровне архитектуры заложено разделение: чтение ссылочной информации разрешено для сохранения целостности документов, а чтение закрытых данных и запись объектов блокируются.

Если конфигурация типовая, рекомендуется не переопределять роли вручную, а настроить типовые группы доступа с видами ограничений «Подразделения» или «Группы физических лиц».

Решение 3. Ограничение на уровне интерфейса (без RLS на чтение)

Если бизнес-требование заключается не в сокрытии существования сотрудников, а исключительно в запрете операторам вручную выбирать «чужих» сотрудников в документы, задачу проще и эффективнее решить без тяжелых RLS-ограничений:

  1. Оставляем право Чтение на справочник сотрудников полным (без RLS).
  2. В свойствах реквизита табличной части документа настраиваем СвязиПараметровВыбора или ПараметрыВыбора по подразделению шапки документа.
  3. В динамическом списке формы выбора справочника Сотрудники устанавливаем фиксированный отбор по доступным пользователю подразделениям в событии ПриСозданииНаСервере:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ГоловноеПодразделение");
	ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
	ЭлементОтбора.ПравоеЗначение = ПараметрыСеанса.ДоступныеПодразделения;
	ЭлементОтбора.Использование = Истина;
КонецПроцедуры

Такой подход полностью исключает появление «Объект не найден», не создает нагрузки на СУБД и надежно защищает от ошибочного выбора неподходящих сотрудников.

Почему нельзя использовать сложные подзапросы к документам в RLS?

Иногда возникает идея добавить в условие RLS справочника сотрудников проверку документов, например: Сотрудник В (ВЫБРАТЬ Табель.Сотрудник ИЗ ...). Рассмотрим, почему так делать категорически не рекомендуется:

  1. Критическое падение производительности: при каждом чтении списка сотрудников или формировании любого отчета СУБД будет выполнять тяжелое соединение с таблицами документов, что приведет к длительным зависаниям базы.
  2. Взаимоблокировки (Deadlocks): перекрестные запросы между справочниками и документами в условиях RLS провоцируют блокировки на уровне СУБД при параллельной работе нескольких пользователей.

Таким образом, наиболее надежным решением проблемы «Объект не найден» является разделение прав RLS по полям (открытый доступ к Ссылка и Наименование) либо использование интерфейсных отборов при выборе.

← На главную