В практике разработчика 1С часто встречается ситуация: после обновления платформы или изменения режима совместимости конфигурации (например, с 8.3.10 на 8.3.13 и выше) внезапно перестают открываться формы списков. Пользователи получают ошибку вида Ошибка при исполнении запроса набора данных с пояснением, что конкретное поле не найдено, хотя права на «Чтение» объекта у пользователя есть. Проанализируем, почему это происходит и как правильно настроить систему прав в современных реалиях платформы 1С:Предприятие.
Разберем ситуацию на классическом примере из типовой конфигурации. Допустим, у нас есть динамический список справочника КартыЛояльности. В запросе этого списка происходит обращение к реквизиту владельца через точку, чтобы проверить его статус или пометку удаления. Рассмотрим типичный фрагмент запроса:
ВЫБОР
КОГДА СправочникКартыЛояльности.Владелец.ПометкаУдаления
ТОГДА ЗНАЧЕНИЕ(Перечисление.СостоянияКартЛояльности.ПустаяСсылка)
ИНАЧЕ ...
КОНЕЦ КАК Состояние
При использовании режима совместимости 8.3.10 такой запрос успешно отрабатывал, если у пользователя было установлено право Чтение на справочник-владелец. Однако, начиная с более новых версий платформы, система начинает выдавать ошибку {(38, 45)}: Поле не найдено "СправочникКартыЛояльности.Владелец.ПометкаУдаления".
Выясним причину: платформа разграничивает права доступа на уровне базы данных и на уровне интерфейса. Чтение (Read) — это право программного доступа к данным (через объект Запрос в коде). Просмотр (View) — это интерактивное право, которое позволяет отображать данные в элементах управления, таких как динамические списки, поля ввода и формы. Для динамического списка, который является визуальным компонентом, право «Просмотр» является обязательным для всех полей, участвующих в построении выборки.
Рассмотрим подробнее механизм «разыменования» (обращения через точку). Когда мы пишем СправочникКартыЛояльности.Владелец, система берет ссылку, которая уже физически хранится в таблице карт лояльности. Для этого достаточно права «Чтение» на сами карты.
Но как только мы пишем СправочникКартыЛояльности.Владелец.ПометкаУдаления, платформа выполняет неявное соединение (LEFT JOIN) с таблицей владельца. В новых режимах совместимости (8.3.11+) построитель запроса динамического списка проверяет наличие права Просмотр на целевую таблицу (Владелец) и её поля. Если этого права нет, поле исключается из доступных метаданных списка. Если это поле задействовано в конструкции ВЫБОР КОГДА, расчет становится невозможным, и система сообщает, что поле «не найдено».
Многие разработчики привыкли использовать ключевое слово РАЗРЕШЕННЫЕ для обхода проблем с правами. Однако в динамическом списке логика работы иная:
РАЗРЕШЕННЫЕ отсекает записи (строки), к которым нет доступа.Самый простой и правильный с точки зрения логики платформы способ — предоставить пользователю право Просмотр на объект, к которому идет обращение через точку. Проанализируем шаги:
ВидыКартЛояльности), который является владельцем.Если бизнес-логика запрещает пользователю видеть все данные владельца, но нам нужно техническое поле (например, ПометкаУдаления) для расчета в списке, можно использовать тонкую настройку прав:
Таким образом, динамический список сможет вычислить условие, но пользователь не увидит лишней информации в других местах интерфейса.
В некоторых случаях помогает переход от разыменования через точку к явному левому соединению в тексте запроса динамического списка. Рассмотрим на примере:
ВЫБРАТЬ
Карты.Ссылка,
Карты.Владелец,
ВЫБОР
КОГДА ТаблицаВладельца.ПометкаУдаления ТОГДА ИСТИНА
ИНАЧЕ ЛОЖЬ
КОНЕЦ КАК ВладелецУдален
ИЗ
Справочник.КартыЛояльности КАК Карты
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ВидыКартЛояльности КАК ТаблицаВладельца
ПО Карты.Владелец = ТаблицаВладельца.Ссылка
Хотя этот метод иногда позволяет обойти жесткую проверку метаданных «через точку», в последних версиях платформы (8.3.15+) проверка прав стала еще строже, и для ТаблицаВладельца.ПометкаУдаления все равно потребуется право Просмотр. Однако этот метод полезен для оптимизации производительности, так как вы сами контролируете условия соединения.
Если предоставление прав на просмотр категорически невозможно, разберем альтернативный вариант — перенос логики из запроса динамического списка в событие ПриПолученииДанныхНаСервере. Посмотрим на алгоритм:
"" КАК СтатусТекст).ПриПолученииДанныхНаСервере выполните запрос в привилегированном режиме:
&НаСервере
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
УстановитьПривилегированныйРежим(Истина);
// Получаем ссылки из структуры Строки, делаем запрос к БД
// и заполняем данные в колонках оформления
КонецПроцедуры
Проанализируем этот подход: он позволяет обойти любые ограничения прав, так как код выполняется на сервере в привилегированном режиме. Однако помните, что это может замедлить работу списка при большом количестве данных и лишит пользователя возможности сортировки или фильтрации по этой колонке, так как она не будет присутствовать в основном запросе БД.
Мы выяснили, что ошибка «Поле не найдено» в динамическом списке при переходе на новые релизы платформы 1С — это не баг, а следствие ужесточения контроля прав. Платформа требует явного разрешения на Просмотр для всех данных, которые выводятся на экран или участвуют в условиях вывода. Для исправления ситуации рекомендуется либо пересмотреть матрицу прав доступа, добавив право «Просмотр», либо использовать механизмы RLS на уровне полей для сохранения конфиденциальности данных.