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