При внедрении ограничений на уровне записей (RLS) для справочника Сотрудники разработчики часто сталкиваются с неприятной ситуацией: если сотрудник из недоступного пользователю подразделения попадает в документ (например, в ТабельУчетаРабочегоВремени через внешнюю загрузку или по совместительству), пользователь видит вместо его ФИО системную заглушку «<Объект не найден [УИД]>».
Разберем детально механизм возникновения этой проблемы в платформе 1С:Предприятие 8, а также рассмотрим архитектурно правильные способы ее решения без потери производительности базы данных.
Проанализируем, как платформа 1С отображает ссылочные данные в формах и списках. Когда в роли для права Чтение задается единое общее условие RLS на всю таблицу справочника (без детализации по конкретным полям), платформа блокирует доступ к записи целиком.
Это означает, что для пользователя становятся недоступными не только реквизиты объекта, но и его ссылка, код и наименование. При открытии документа платформа пытается получить строковое представление ссылки из табличной части, однако СУБД возвращает пустой результат из-за наложенного ограничения RLS. В результате интерфейс платформы отображает строку «<Объект не найден>».
Самый эффективный и правильный способ в рамках собственной настройки RLS — разделить право на чтение полей представления и остальных реквизитов объекта.
Выполним настройку роли в конфигураторе по следующим шагам:
Сотрудники на вкладку Ограничение доступа к данным для права Чтение.Ссылка, Наименование (или ФИО), Код. Для этой строки условие ограничения оставляем пустым или указываем ГДЕ ИСТИНА. Это дает платформе возможность считывать ссылки и выводить наименования сотрудников во всех документах, отчетах и списках без ошибок.<Прочие поля>. Здесь прописываем рабочее условие ограничения по подразделению (например, через параметры сеанса).Посмотрим на пример логики условия для поля <Прочие поля>:
ГДЕ ТекущаяТаблица.ГоловноеПодразделение В (&ДоступныеПодразделения)
При такой схеме пользователь видит ФИО сотрудника в табличной части документа, однако при попытке открыть форму самого элемента справочника платформа корректно сообщит о нарушении прав доступа, так как закрыт доступ к основным реквизитам объекта.
В типовых конфигурациях (включая 1С:ЗУП редакции 3) прямой код RLS в ролях практически не разрабатывается вручную с нуля. Вместо этого применяется механизм управления доступом на базе Библиотеки стандартных подсистем (БСП) в производительном режиме.
В типовой подсистеме доступ рассчитывается через регистры сведений КлючиДоступаКОбъектам и КлючиДоступаПользователей с использованием шаблонов ПоЗначениям и ПоЗначениямРасширенный. В этих шаблонах уже на уровне архитектуры заложено разделение: чтение ссылочной информации разрешено для сохранения целостности документов, а чтение закрытых данных и запись объектов блокируются.
Если конфигурация типовая, рекомендуется не переопределять роли вручную, а настроить типовые группы доступа с видами ограничений «Подразделения» или «Группы физических лиц».
Если бизнес-требование заключается не в сокрытии существования сотрудников, а исключительно в запрете операторам вручную выбирать «чужих» сотрудников в документы, задачу проще и эффективнее решить без тяжелых RLS-ограничений:
СвязиПараметровВыбора или ПараметрыВыбора по подразделению шапки документа.Сотрудники устанавливаем фиксированный отбор по доступным пользователю подразделениям в событии ПриСозданииНаСервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ГоловноеПодразделение");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
ЭлементОтбора.ПравоеЗначение = ПараметрыСеанса.ДоступныеПодразделения;
ЭлементОтбора.Использование = Истина;
КонецПроцедуры
Такой подход полностью исключает появление «Объект не найден», не создает нагрузки на СУБД и надежно защищает от ошибочного выбора неподходящих сотрудников.
Иногда возникает идея добавить в условие RLS справочника сотрудников проверку документов, например: Сотрудник В (ВЫБРАТЬ Табель.Сотрудник ИЗ ...). Рассмотрим, почему так делать категорически не рекомендуется:
Таким образом, наиболее надежным решением проблемы «Объект не найден» является разделение прав RLS по полям (открытый доступ к Ссылка и Наименование) либо использование интерфейсных отборов при выборе.