При разработке или кастомизации конфигурации 1С:Зарплата и управление персоналом программисты часто сталкиваются с необходимостью изменения структуры документов. Типичный пример — переход от назначения документа одному сотруднику (через реквизит шапки) к списку сотрудников (через табличную часть). Однако после такого изменения стандартные механизмы ограничения доступа на уровне записей (RLS) могут перестать работать. Рассмотрим подробно, почему это происходит и как правильно настроить расширенные шаблоны ограничений.
В современных версиях ЗУП 3.1, построенных на базе Библиотеки стандартных подсистем (БСП), используется универсальный механизм ограничения доступа. Прежде чем приступать к правке кода, проанализируем текущую ситуацию. Ограничение доступа может работать в двух режимах: стандартном и производительном. Если в конфигурации включен производительный режим, то простым изменением текста запроса в метаданных проблему не решить, так как данные о правах кэшируются в специальных регистрах сведений.
Посмотрим на конструкцию, которую обычно используют в начале текста RLS:
#Если &ОграничениеДоступаНаУровнеЗаписейУниверсально #Тогда
#ДляОбъекта("")
#Иначе
...
#КонецЕсли
Эта инструкция проверяет, используется ли новый универсальный механизм. Если да, то для объекта применяются общие настройки. Однако, если мы пишем кастомный запрос в секции #Иначе, мы работаем со "старым" методом формирования условий SQL, который платформа подставляет в каждый запрос к базе данных.
Рассмотрим пример кода, который часто вызывает затруднения. Основная ошибка заключается в логике соединения таблиц. Выясним причину: когда данные находились в шапке, системе было достаточно проверить одно поле. При переходе к табличной части (ТЧ) программисты пытаются использовать ЛЕВОЕ СОЕДИНЕНИЕ (LEFT JOIN) с вложенным запросом UNION ALL, чтобы объединить данные из шапки (если они там остались) и из новой табличной части.
Проанализируем фрагмент кода пользователя:
#ПоЗначениямРасширенный("Документ.УдержаниеВСчетРасчетовПоПрочимОперациям","Чтение","","",
" Левое СОЕДИНЕНИЕ (ВЫБРАТЬ
УдержаниеВСчетРасчетовПоПрочимОперациямСотрудники.ФизическоеЛицо КАК ФизическоеЛицо,
УдержаниеВСчетРасчетовПоПрочимОперациямСотрудники.Ссылка КАК Ссылка
ИЗ
Документ.УдержаниеВСчетРасчетовПоПрочимОперациям.Сотрудники КАК УдержаниеВСчетРасчетовПоПрочимОперациямСотрудники
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
УдержаниеВСчетРасчетовПоПрочимОперациям.ФизическоеЛицо,
УдержаниеВСчетРасчетовПоПрочимОперациям.Ссылка
ИЗ
Документ.УдержаниеВСчетРасчетовПоПрочимОперациям КАК УдержаниеВСчетРасчетовПоПрочимОперациям) КАК Т10
ПО Т.Ссылка = Т10.Ссылка
","",""," И ",
"ГруппыФизическихЛиц","Т10.ФизическоеЛицо",")И",
"Организации","Организация","",
...
Разберем по шагам, что здесь не так:
Т10.ФизическоеЛицо вернет NULL. В механизме прав доступа NULL может интерпретироваться как отсутствие ограничений, что приведет к полному открытию доступа или, наоборот, к его непредсказуемой блокировке.")И". Лишние закрывающие скобки или отсутствие пробелов в строковых параметрах шаблона #ПоЗначениямРасширенный часто приводят к тому, что результирующий запрос оказывается синтаксически неверным. Платформа просто игнорирует такое ограничение или выдает ошибку при попытке чтения данных.ОБЪЕДИНИТЬ ВСЕ внутри шаблона существенно замедляет работу. Если документ содержит 100 сотрудников, RLS создаст огромную выборку в памяти для каждой проверки.Выясним, как сделать правильно. Если мы полностью перешли на использование табличной части, нам больше не нужно объединять её с шапкой. Нам необходимо использовать внутреннее соединение с таблицей сотрудников. Разберем правильный подход.
Для корректной работы ограничения по Группам физических лиц в 1С:ЗУП, система должна сопоставить физическое лицо из документа с группами, в которые оно входит. Это происходит через обращение к параметрам сеанса или вспомогательным таблицам прав. Чтобы шаблон #ПоЗначениямРасширенный отработал, в поле ОбъектДоступа (второй параметр после имени группы доступа) должно попадать конкретное поле из таблицы.
Рассмотрим пример исправленного шаблона:
#ПоЗначениямРасширенный("Документ.ВашДокумент","Чтение","","",
"ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ВашДокумент.Сотрудники КАК Т10
ПО Т.Ссылка = Т10.Ссылка","",""," И ",
"ГруппыФизическихЛиц","Т10.ФизическоеЛицо","",
"Организации","Организация","",
"","","", "","","", "","","", "","","")
В данном случае мы используем ВНУТРЕННЕЕ СОЕДИНЕНИЕ. Это гарантирует, что если в документе есть сотрудники, к которым у пользователя нет доступа, то и весь документ (в зависимости от настроек прав) может быть скрыт. Если же логика требует, чтобы документ был виден, если доступен хотя бы один сотрудник из списка, то структура запроса должна быть иной — через проверку существования (ВЫБРАТЬ 1 ИЗ... ГДЕ...).
Проанализируем еще несколько критических моментов, без которых RLS не заработает даже с правильным кодом:
ФизическоеЛицо в вашей новой табличной части имеет тип СправочникСсылка.ФизическиеЛица. Если там используется другой тип (например, СправочникСсылка.Сотрудники), механизм RLS по группам физлиц может не найти связь, так как он настроен именно на справочник физических лиц.ОбновлениеДоступаНаУровнеЗаписей.Если после всех правок ограничение всё равно не работает, проделаем следующие действия:
Во-первых, воспользуйтесь консолью запросов. Запустите её под пользователем с ограниченными правами и попробуйте выполнить простой запрос: ВЫБРАТЬ * ИЗ Документ.ИмяВашегоДокумента. Если консоль выдает ошибку "Ошибка в тексте RLS", значит, в вашем шаблоне есть опечатки в скобках или кавычках.
Во-вторых, временно уберите из шаблона проверку по ГруппамФизическихЛиц, оставив только Организации. Если по организациям доступ ограничивается корректно, значит проблема именно в соединении с табличной частью или в правах на само физическое лицо.
В-третьих, проверьте, включена ли в профиле групп доступа сама возможность ограничения по физическим лицам. В ЗУП это часто настраивается через "Виды доступа". Если вид доступа "Физические лица" не активен в профиле, то никакой код в RLS не заставит систему фильтровать данные по этому критерию.
Таким образом, для успешного решения задачи нам необходимо: заменить левое соединение на корректное внутреннее, настроить управление доступом к формам, проверить соответствие типов данных в табличной части, обеспечить контроль видимости элементов и убедиться, что синтаксис параметров расширенного шаблона БСП соблюден до каждого пробела.