Почему в динамическом списке возникает ошибка «Поле не найдено» при наличии прав на чтение и как это исправить

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

В практике разработчика 1С часто встречается ситуация: после обновления платформы или изменения режима совместимости конфигурации (например, с 8.3.10 на 8.3.13 и выше) внезапно перестают открываться формы списков. Пользователи получают ошибку вида Ошибка при исполнении запроса набора данных с пояснением, что конкретное поле не найдено, хотя права на «Чтение» объекта у пользователя есть. Проанализируем, почему это происходит и как правильно настроить систему прав в современных реалиях платформы 1С:Предприятие.

Суть проблемы: Чтение vs Просмотр

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


ВЫБОР
    КОГДА СправочникКартыЛояльности.Владелец.ПометкаУдаления
    ТОГДА ЗНАЧЕНИЕ(Перечисление.СостоянияКартЛояльности.ПустаяСсылка)
    ИНАЧЕ ...
КОНЕЦ КАК Состояние

При использовании режима совместимости 8.3.10 такой запрос успешно отрабатывал, если у пользователя было установлено право Чтение на справочник-владелец. Однако, начиная с более новых версий платформы, система начинает выдавать ошибку {(38, 45)}: Поле не найдено "СправочникКартыЛояльности.Владелец.ПометкаУдаления".

Выясним причину: платформа разграничивает права доступа на уровне базы данных и на уровне интерфейса. Чтение (Read) — это право программного доступа к данным (через объект Запрос в коде). Просмотр (View) — это интерактивное право, которое позволяет отображать данные в элементах управления, таких как динамические списки, поля ввода и формы. Для динамического списка, который является визуальным компонентом, право «Просмотр» является обязательным для всех полей, участвующих в построении выборки.

Особенности разыменования в динамических списках

Рассмотрим подробнее механизм «разыменования» (обращения через точку). Когда мы пишем СправочникКартыЛояльности.Владелец, система берет ссылку, которая уже физически хранится в таблице карт лояльности. Для этого достаточно права «Чтение» на сами карты.

Но как только мы пишем СправочникКартыЛояльности.Владелец.ПометкаУдаления, платформа выполняет неявное соединение (LEFT JOIN) с таблицей владельца. В новых режимах совместимости (8.3.11+) построитель запроса динамического списка проверяет наличие права Просмотр на целевую таблицу (Владелец) и её поля. Если этого права нет, поле исключается из доступных метаданных списка. Если это поле задействовано в конструкции ВЫБОР КОГДА, расчет становится невозможным, и система сообщает, что поле «не найдено».

Почему не помогает ВЫБРАТЬ РАЗРЕШЕННЫЕ

Многие разработчики привыкли использовать ключевое слово РАЗРЕШЕННЫЕ для обхода проблем с правами. Однако в динамическом списке логика работы иная:

  1. Ключевое слово РАЗРЕШЕННЫЕ отсекает записи (строки), к которым нет доступа.
  2. Отсутствие права Просмотр на колонку или реквизит объекта удаляет саму колонку из схемы запроса для интерфейса.
  3. Если логика формирования другой колонки (вычисляемого поля) зависит от этого «удаленного» поля, весь запрос списка становится невалидным.

Способ 1: Установка права «Просмотр» (Рекомендуемый)

Самый простой и правильный с точки зрения логики платформы способ — предоставить пользователю право Просмотр на объект, к которому идет обращение через точку. Проанализируем шаги:

Способ 2: Ограничение прав на уровне полей (RLS по полям)

Если бизнес-логика запрещает пользователю видеть все данные владельца, но нам нужно техническое поле (например, ПометкаУдаления) для расчета в списке, можно использовать тонкую настройку прав:

  1. Дайте право Просмотр на объект в целом.
  2. В списке реквизитов этого объекта снимите флаг Просмотр со всех конфиденциальных полей (например, ИНН, Сумма, Спецификация).
  3. Оставьте флаг Просмотр только для системных полей и тех полей, которые нужны для динамического списка.

Таким образом, динамический список сможет вычислить условие, но пользователь не увидит лишней информации в других местах интерфейса.

Способ 3: Явное соединение в запросе

В некоторых случаях помогает переход от разыменования через точку к явному левому соединению в тексте запроса динамического списка. Рассмотрим на примере:


ВЫБРАТЬ
    Карты.Ссылка,
    Карты.Владелец,
    ВЫБОР
        КОГДА ТаблицаВладельца.ПометкаУдаления ТОГДА ИСТИНА
        ИНАЧЕ ЛОЖЬ
    КОНЕЦ КАК ВладелецУдален
ИЗ
    Справочник.КартыЛояльности КАК Карты
    ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ВидыКартЛояльности КАК ТаблицаВладельца
    ПО Карты.Владелец = ТаблицаВладельца.Ссылка

Хотя этот метод иногда позволяет обойти жесткую проверку метаданных «через точку», в последних версиях платформы (8.3.15+) проверка прав стала еще строже, и для ТаблицаВладельца.ПометкаУдаления все равно потребуется право Просмотр. Однако этот метод полезен для оптимизации производительности, так как вы сами контролируете условия соединения.

Способ 4: Обработка данных на сервере

Если предоставление прав на просмотр категорически невозможно, разберем альтернативный вариант — перенос логики из запроса динамического списка в событие ПриПолученииДанныхНаСервере. Посмотрим на алгоритм:

  1. Удалите проблемное поле из запроса динамического списка.
  2. Добавьте в динамический список пустую колонку (через "" КАК СтатусТекст).
  3. В процедуре ПриПолученииДанныхНаСервере выполните запрос в привилегированном режиме:

&НаСервере
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
    УстановитьПривилегированныйРежим(Истина);
    // Получаем ссылки из структуры Строки, делаем запрос к БД
    // и заполняем данные в колонках оформления
КонецПроцедуры

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

Выводы

Мы выяснили, что ошибка «Поле не найдено» в динамическом списке при переходе на новые релизы платформы 1С — это не баг, а следствие ужесточения контроля прав. Платформа требует явного разрешения на Просмотр для всех данных, которые выводятся на экран или участвуют в условиях вывода. Для исправления ситуации рекомендуется либо пересмотреть матрицу прав доступа, добавив право «Просмотр», либо использовать механизмы RLS на уровне полей для сохранения конфиденциальности данных.

← На главную