Как исправить ошибку «Поле не найдено» при программном получении управляемой формы

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

При разработке на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда код, идеально работающий под полными правами, начинает выдавать странные ошибки в сеансе обычного пользователя. Одной из таких проблем является ошибка динамического списка при программном открытии формы. Рассмотрим типичный сценарий: при входе пользователя с определенной ролью система должна автоматически открыть форму списка документов, но вместо этого выдает сообщение: Поле не найдено "СчетОтИсполнителяНаряды.Ссылка.ПометкаУдаления". Проанализируем, почему это происходит и как правильно решить эту задачу.

Разбор ситуации: анализ исходного кода

Рассмотрим пример кода, который часто пишут в модуле управляемого приложения для реализации стартового экрана:


Если ОбщегоНазначенияКлиент.ДоступнаРольWEBПользователь() И КоличествоРолей = 1 Тогда
    Форма = ПолучитьФорму("Документ.Наряд.Форма.ФормаСпискаУпр");
    Форма.Открыть();
КонецЕсли;

На первый взгляд, код логичен. Однако именно здесь кроются две основные проблемы: методическая (способ открытия формы) и инфраструктурная (права доступа). Выясним причину ошибки динамического списка, которая возникает в момент выполнения метода ПолучитьФорму().

Причина 1: Особенности механизма RLS и прав доступа

Ошибка Поле не найдено "ИмяТаблицы.Ссылка.ПометкаУдаления" практически всегда указывает на проблему с правами доступа на уровне записей (RLS). Разберем по шагам, что происходит внутри системы:

  1. Динамический список на форме использует запрос, который обращается к табличной части (ТЧ) документа.
  2. В запросе происходит обращение «через точку» от табличной части к реквизиту основного документа: СчетОтИсполнителяНаряды.Ссылка.ПометкаУдаления.
  3. У пользователя есть права на чтение самой табличной части, но отсутствуют права на чтение основного объекта (Документа).
  4. Платформа 1С при исполнении запроса под ограниченными правами не может «разыменовать» ссылку. Для системы поле Ссылка становится недоступным, а попытка получить от него ПометкаУдаления приводит к тому, что поле считается отсутствующим в схеме базы данных для данного контекста.

Решение: Проверьте роли пользователя. Необходимо убедиться, что роль, назначенная пользователю, дает право не только на просмотр конкретных реквизитов или табличных частей, но и базовое право Чтение и Просмотр на сам объект метаданных (в данном случае — Документ).

Причина 2: Использование ПолучитьФорму() вместо ОткрытьФорму()

Методическая ошибка заключается в использовании метода ПолучитьФорму() в управляемом приложении. Рассмотрим подробнее, чем это грозит:

Когда мы вызываем ПолучитьФорму(), платформа инициирует серверный вызов для создания экземпляра формы. Весь контекст формы передается на клиент. Затем, вызывая .Открыть(), мы снова обращаемся к серверу. Это создает лишнюю нагрузку на сеть и сервер. Но главная проблема в другом: при получении формы без открытия инициализация динамических списков может происходить некорректно в контексте прав доступа текущего сеанса.

Решение: В управляемом интерфейсе всегда следует использовать метод ОткрытьФорму(). Он оптимизирован: выполнение происходит за один клиент-серверный цикл, и форма инициализируется сразу с учетом всех параметров сеанса.

Исправленный код будет выглядеть так:


ПараметрыФормы = Новый Структура;
ОткрытьФорму("Документ.Наряд.Форма.ФормаСпискаУпр", ПараметрыФормы);

Причина 3: Обращение «через точку» в запросах динамического списка

Проанализируем запрос динамического списка. Использование конструкций вида ТЧ.Ссылка.Реквизит в текстах запросов является «плохим тоном» с точки зрения производительности и безопасности прав доступа. Каждое такое обращение платформа преобразует в неявное левое соединение (LEFT JOIN).

Для исправления ошибки и повышения стабильности работы системы рекомендуем переписать запрос динамического списка, используя явное соединение:


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

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

Дополнительные рекомендации по диагностике

Если вы столкнулись с подобной ситуацией, и конфигуратор не видит ошибок в запросе, выполните следующие действия:

  1. Проверка под пользователем: Запустите консоль запросов в пользовательском режиме под учетной записью того пользователя, у которого возникает ошибка. Попробуйте выполнить запрос динамического списка. Вы увидите реальную картину прав доступа.
  2. Анализ функциональных опций: Выясним, не привязан ли реквизит ПометкаУдаления или сам документ к какой-либо функциональной опции. Если опция выключена для данного пользователя, поле физически исключается из метаданных в этом сеансе.
  3. Программная проверка прав: Вместо жесткой проверки ролей используйте более гибкий метод ПравоДоступа().

Пример правильной проверки прав перед открытием формы:


Если ПравоДоступа("Чтение", Метаданные.Документы.Наряд) Тогда
    ОткрытьФорму("Документ.Наряд.Форма.ФормаСпискаУпр");
КонецЕсли;

Подводя итог, можно сказать, что решение проблемы кроется в комплексном подходе: обеспечении минимально необходимых прав на объекты-владельцы, использовании оптимизированных методов открытия форм ОткрытьФорму() и отказе от сложных обращений через точку в динамических списках в пользу явных соединений.

← На главную