Как исправить ошибку «Основная таблица динамического списка задана неверно» при использовании временных таблиц в 1С?

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

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

Разберем детально, почему платформа 1С выдает данное сообщение, как устроена работа динамического списка и какими способами можно правильно решить эту задачу.

Выясним причину возникновения ошибки

Для понимания корня проблемы проанализируем, за что отвечает свойство ОсновнаяТаблица у динамического списка на управляемой форме. Когда в свойствах реквизита списка указана основная таблица (например, ЖурналДокументов.СкладскиеОрдера), платформа берет на себя управление следующими механизмами:

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

Механизм платформы жестко требует: если в свойствах динамического списка заполнено поле ОсновнаяТаблица, то таблица именно этого объекта метаданных должна присутствовать в явном виде в секции ИЗ или ЛЕВОЕ СОЕДИНЕНИЕ самого последнего (результирующего) запроса пакета.

Посмотрим на фрагмент завершающего запроса, который привел к ошибке:


ВЫБРАТЬ РАЗРЕШЕННЫЕ
    СкладскиеОрдера.Ссылка КАК Ссылка,
    СкладскиеОрдера.Дата КАК Дата,
    ...
ИЗ
    ВТ_Ордера КАК СкладскиеОрдера
    ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Итговая КАК ВТ_Итговая
    ПО СкладскиеОрдера.Ссылка = ВТ_Итговая.Ссылка

В приведенном коде последняя выборка выполняется из временной таблицы ВТ_Ордера. Несмотря на то что во временную таблицу изначально помещались данные из ЖурналДокументов.СкладскиеОрдера, для платформы временная таблица — это абстрактный набор полей. Платформа не может связать строки результирующей выборки с физической таблицей базы данных, что и вызывает исключение.

Способ 1. Соединение с исходной таблицей в результирующем запросе

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


ВЫБРАТЬ РАЗРЕШЕННЫЕ
    ЖурналДокументовСкладскиеОрдера.Ссылка КАК Ссылка,
    ЖурналДокументовСкладскиеОрдера.Дата КАК Дата,
    ЖурналДокументовСкладскиеОрдера.ПометкаУдаления КАК ПометкаУдаления,
    ЖурналДокументовСкладскиеОрдера.Номер КАК Номер,
    ЖурналДокументовСкладскиеОрдера.Проведен КАК Проведен,
    ЖурналДокументовСкладскиеОрдера.Статус КАК Статус,
    ЖурналДокументовСкладскиеОрдера.Комментарий КАК Комментарий,
    ЖурналДокументовСкладскиеОрдера.ПомещениеОтправитель КАК ПомещениеОтправитель,
    ЖурналДокументовСкладскиеОрдера.Приоритет КАК Приоритет,
    ЖурналДокументовСкладскиеОрдера.ДатаОтгрузки КАК ДатаОтгрузки,
    ЖурналДокументовСкладскиеОрдера.ЗаданиеНаПеревозку КАК ЗаданиеНаПеревозку,
    ЖурналДокументовСкладскиеОрдера.ОтгрузкаПоЗаданиюНаПеревозку КАК ОтгрузкаПоЗаданиюНаПеревозку,
    ЖурналДокументовСкладскиеОрдера.ПорядокДоставки КАК ПорядокДоставки,
    ЖурналДокументовСкладскиеОрдера.ПолучательОтправитель КАК ПолучательОтправитель,
    ЖурналДокументовСкладскиеОрдера.Тип КАК Тип,
    ВТ_Итговая.Перевозчик КАК Перевозчик,
    ВТ_Итговая.Распоряжение КАК ЗаказКлиента,
    ВТ_Итговая.ЕстьСсылкаНаДокумент КАК ЕстьСсылкаНаДокумент,
    ВТ_Итговая.СсылкаНаДокумент КАК СсылкаНаДокумент
ИЗ
    ЖурналДокументов.СкладскиеОрдера КАК ЖурналДокументовСкладскиеОрдера
        ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Итговая КАК ВТ_Итговая
        ПО ЖурналДокументовСкладскиеОрдера.Ссылка = ВТ_Итговая.Ссылка

Теперь платформа четко видит таблицу ЖурналДокументов.СкладскиеОрдера в секции ИЗ и безошибочно сопоставляет строки списка.

Способ 2. Очистка свойства «Основная таблица»

Рассмотрим альтернативный вариант: если форма списка используется исключительно в режиме просмотра или выбора данных, и вам не требуются стандартные команды платформы (проведение документов, контекстное меню смены статусов и т. д.), можно снять требование платформы.

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

Подводные камни производительности временных таблиц в динамических списках

Обратим внимание на критически важный аспект разработки: динамический список выполняет свой запрос многократно — при скроллинге, наложении отборов, сортировке, поиске и обновлении формы. Когда в запросе динамического списка создается цепочка временных таблиц без жестких отборов по периоду, СУБД вынуждена при каждом действии пользователя пересчитывать все промежуточные таблицы (ВТ_Распоряжения, ВТ_Реализации и т. д.) по всей базе данных целиком. Это быстро приводит к зависаниям интерфейса.

Кроме того, конструкция вида СкладскиеОрдера.Ссылка.Реквизит применительно к журналу документов заставляет платформу строить неявные левые соединения со всеми типами документов, входящими в журнал, что создает тяжелую нагрузку на СУБД.

Архитектурно правильные альтернативы

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

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