Почему возникает ошибка «Поле не найдено» в Динамическом списке 1С, если в консоли запрос работает?

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

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

Суть проблемы: отличие Консоли от Динамического списка

Консоль запросов просто выполняет SQL-команду и возвращает результат. Динамический список (ДС) — это гораздо более сложный механизм, работающий на базе Системы Компоновки Данных (СКД). Когда мы помещаем запрос в ДС, платформа должна:

  1. Распарсить текст запроса.
  2. Определить доступные поля для отборов и сортировок.
  3. Определить «Основную таблицу» (для ключей уникальности и динамической подгрузки).

Ошибка «Поле не найдено» (например, ХодОбработки.Действие.ВидДействия.Наименование) возникает не потому, что данных нет, а потому что компоновщик динамического списка не может корректно построить путь к этим данным из-за сложной структуры запроса. Рассмотрим два основных фактора, ломающих динамический список в данном примере.

Фактор 1: Неявные соединения (обращение через точку)

В исходном коде используется глубокое разыменование полей:


ХодОбработки.Действие.ВидДействия.Наименование
ХодОбработки.Обработка.Владелец.Ссылка

Для платформы 1С каждая точка — это неявное ЛЕВОЕ СОЕДИНЕНИЕ (LEFT JOIN). Когда таких соединений становится много, и они происходят внутри условий соединения с временными таблицами, парсер ДС может «запутаться». Особенно критично использование конструкции вида: ПО ... = ХодОбработки.Обработка.Владелец.Ссылка Если поле Владелец имеет составной тип данных (например, может быть ссылкой на Справочник или Документ), то обращение .Ссылка заставляет систему соединяться со всеми возможными таблицами, входящими в этот составной тип. Это создает гигантскую и нестабильную структуру запроса, которую динамический список часто не может обработать на этапе инициализации формы.

Фактор 2: Временные таблицы

Использование конструкции ПОМЕСТИТЬ внутри динамического списка допустимо, но накладывает ограничения. ДС пытается определить основную таблицу из финальной выборки. Если финальная выборка строится на базе временной таблицы, соединенной с другими таблицами через сложные условия (как описано выше), контекст метаданных может потеряться.

Решение 1: Оптимизация запроса (Рекомендуемое)

Самый надежный способ — переписать запрос так, чтобы избавиться от неявных соединений (точек). Заменим их на явные ЛЕВОЕ СОЕДИНЕНИЕ. Вместо обращения ХодОбработки.Действие.ВидДействия.Наименование, добавим явные соединения со справочниками. Пример того, как нужно преобразовать структуру запроса:


ВЫБРАТЬ ПОМЕСТИТЬ ВТ_Документы
ИЗ ...
;

ВЫБРАТЬ
    ВТ_ДокументыПредприятия.*,
    ВидыДействий.Наименование КАК ДействиеНаименование, // Берем поле из явно присоединенной таблицы
    ХодОбработки.Результат
ИЗ
    ВТ_ДокументыПредприятия КАК ВТ_ДокументыПредприятия
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ХодОбработки КАК ХодОбработки
        // Соединяем сразу по нужному полю, избегая лишних точек
        ПО ВТ_ДокументыПредприятия.Заголовок = ХодОбработки.Обработка 
        
        // Явно соединяем для получения реквизитов "Действия"
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ВидыДействий КАК ВидыДействий 
        ПО ХодОбработки.Действие = ВидыДействий.Ссылка

Важно: Избегайте конструкций Владелец.Ссылка в условиях соединения. Если поле Владелец составного типа, используйте функцию ВЫРАЗИТЬ для приведения к конкретному типу перед соединением, либо соединяйте напрямую, если типы совпадают.

Решение 2: Программная установка запроса (Быстрое)

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    ТекстЗапроса = "
    |ВЫБРАТЬ ПОМЕСТИТЬ ВТ_ДокументыПредприятия ... 
    |// ... ваш полный текст запроса ...
    |";
    
    Список.ПроизвольныйЗапрос = Истина;
    Список.ТекстЗапроса = ТекстЗапроса;
    
КонецПроцедуры

Этот метод часто помогает убрать ошибку «Поле не найдено» без изменения самого запроса, но он не решает проблему производительности, создаваемую неявными соединениями.

Рекомендации по отладке

Если вы видите ошибку «Поле не найдено» в параметрах динамического списка:

  1. Проверьте NULL. Убедитесь, что в полях, к которым вы обращаетесь через точку, нет значений NULL или «Битая ссылка». Хотя это чаще вызывает пустые поля, в сложных запросах ДС это может влиять на определение типов.
  2. Упростите выборку. Уберите из списка выбираемых полей (SELECT) все поля с точками. Добавляйте их по одному, чтобы найти конкретное поле, вызывающее сбой.
  3. Проверьте Основную таблицу. В свойствах динамического списка в конфигураторе убедитесь, что свойство ОсновнаяТаблица заполнено (если это возможно для вашего запроса) или, наоборот, очищено, если запрос слишком сложный и собирает данные из равнозначных источников.
← На главную