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

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

Часто при разработке форм подбора или специализированных рабочих мест в 1С возникает необходимость вывести в динамический список строки из документов. Например, мы хотим отобразить товары из табличной части ЗаказКлиента.Товары. Однако при попытке указать эту табличную часть в свойстве «Основная таблица» платформа выдает ошибку: Основная таблица динамического списка задана неверно. Давайте подробно разберем, почему возникает эта ситуация, и рассмотрим эффективные способы ее решения.

Почему нельзя выбрать табличную часть как основную таблицу?

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

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

Решение 1: Использование произвольного запроса без основной таблицы

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

Однако при таком подходе возникают новые нюансы, которые мы должны учитывать при разработке:

  1. Пропадают стандартные команды: Автоматические кнопки «Создать», «Скопировать», «Изменить» исчезнут, так как система больше не понимает, объект какого типа мы планируем редактировать.
  2. Изменяется тип выбранной строки: При двойном клике или в обработчике события Выбор переменная ВыбраннаяСтрока вернет не ссылку на объект, а значение ключевого поля (например, просто номер строки).

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


&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    
    // Внимание: здесь ВыбраннаяСтрока может содержать просто номер строки, а не ссылку!
    // Прямой поиск по ней приведет к ошибке логики.
    НайденныеСтроки = Корзина.НайтиСтроки(Новый Структура("Номенклатура", ВыбраннаяСтрока));
    
    Если НайденныеСтроки.Количество() > 0 Тогда
        НайденныеСтроки[0].Количество = НайденныеСтроки[0].Количество + 1;
    Иначе
        НоваяСтрока = Корзина.Добавить();
        НоваяСтрока.Номенклатура = ВыбраннаяСтрока; // Ошибка: передается номер строки
        НоваяСтрока.Количество = 1;
    КонецЕсли;
КонецПроцедуры

Чтобы код работал корректно, нам нужно получить фактические данные строки по переданному идентификатору. Сделаем это с помощью метода ДанныеСтроки():


&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    
    // Получаем реальные данные строки из динамического списка
    ДанныеВыбраннойСтроки = Элементы.Список.ДанныеСтроки(ВыбраннаяСтрока);
    Товар = ДанныеВыбраннойСтроки.Номенклатура;
    
    НайденныеСтроки = Корзина.НайтиСтроки(Новый Структура("Номенклатура", Товар));
    
    Если НайденныеСтроки.Количество() > 0 Тогда
        НайденныеСтроки[0].Количество = НайденныеСтроки[0].Количество + 1;
    Иначе
        НоваяСтрока = Корзина.Добавить();
        НоваяСтрока.Номенклатура = Товар;
        НоваяСтрока.Количество = 1;
    КонецЕсли;
КонецПроцедуры

Также альтернативным и зачастую более предпочтительным способом является использование свойства ТекущиеДанные:


ТекущиеДанные = Элементы.Список.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено Тогда
    Товар = ТекущиеДанные.Номенклатура;
КонецЕсли;

Важный нюанс: Настройка ключевого поля

Проанализируем настройку самого запроса. Чтобы динамический список без основной таблицы не "прыгал" при прокрутке и работал корректно, мы обязательно должны настроить колонку Ключ на вкладке «Настройка списка» -> «Запрос». Для выборки из табличной части в качестве ключа обычно указывают уникальную комбинацию полей или скрытое поле-идентификатор. Если этого не сделать, возможны дубли визуального представления строк.

Решение 2: Альтернативная архитектура для подбора

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

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

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

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

← На главную