Часто при разработке форм подбора или специализированных рабочих мест в 1С возникает необходимость вывести в динамический список строки из документов. Например, мы хотим отобразить товары из табличной части ЗаказКлиента.Товары. Однако при попытке указать эту табличную часть в свойстве «Основная таблица» платформа выдает ошибку: Основная таблица динамического списка задана неверно. Давайте подробно разберем, почему возникает эта ситуация, и рассмотрим эффективные способы ее решения.
Для начала выясним причину такого поведения платформы. В системе 1С:Предприятие 8 свойство «Основная таблица» может принимать только те объекты базы данных, которые имеют постоянный уникальный идентификатор (UUID). К таким объектам относятся справочники, документы, планы видов характеристик, а также записи независимых регистров сведений.
Табличные части документов не являются самостоятельными сущностями. Они всегда жестко привязаны к своему владельцу (конкретному документу) и идентифицируются в базе только комбинацией «Ссылка на документ + Номер строки». Именно поэтому платформа технически не может назначить табличную часть основной таблицей динамического списка.
Если нам необходимо вывести именно строки документов, мы можем перевести динамический список в режим Произвольный запрос и оставить поле «Основная таблица» пустым. При открытии формы данные успешно выведутся, и ошибки не будет.
Однако при таком подходе возникают новые нюансы, которые мы должны учитывать при разработке:
Выбор переменная ВыбраннаяСтрока вернет не ссылку на объект, а значение ключевого поля (например, просто номер строки).Рассмотрим пример. Допустим, мы пишем обработчик для подбора номенклатуры в корзину при двойном щелчке по списку:
&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Внимание: здесь ВыбраннаяСтрока может содержать просто номер строки, а не ссылку!
// Прямой поиск по ней приведет к ошибке логики.
НайденныеСтроки = Корзина.НайтиСтроки(Новый Структура("Номенклатура", ВыбраннаяСтрока));
Если НайденныеСтроки.Количество() > 0 Тогда
НайденныеСтроки[0].Количество = НайденныеСтроки[0].Количество + 1;
Иначе
НоваяСтрока = Корзина.Добавить();
НоваяСтрока.Номенклатура = ВыбраннаяСтрока; // Ошибка: передается номер строки
НоваяСтрока.Количество = 1;
КонецЕсли;
КонецПроцедуры
Чтобы код работал корректно, нам нужно получить фактические данные строки по переданному идентификатору. Сделаем это с помощью метода ДанныеСтроки():
&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Получаем реальные данные строки из динамического списка
ДанныеВыбраннойСтроки = Элементы.Список.ДанныеСтроки(ВыбраннаяСтрока);
Товар = ДанныеВыбраннойСтроки.Номенклатура;
НайденныеСтроки = Корзина.НайтиСтроки(Новый Структура("Номенклатура", Товар));
Если НайденныеСтроки.Количество() > 0 Тогда
НайденныеСтроки[0].Количество = НайденныеСтроки[0].Количество + 1;
Иначе
НоваяСтрока = Корзина.Добавить();
НоваяСтрока.Номенклатура = Товар;
НоваяСтрока.Количество = 1;
КонецЕсли;
КонецПроцедуры
Также альтернативным и зачастую более предпочтительным способом является использование свойства ТекущиеДанные:
ТекущиеДанные = Элементы.Список.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено Тогда
Товар = ТекущиеДанные.Номенклатура;
КонецЕсли;
Проанализируем настройку самого запроса. Чтобы динамический список без основной таблицы не "прыгал" при прокрутке и работал корректно, мы обязательно должны настроить колонку Ключ на вкладке «Настройка списка» -> «Запрос». Для выборки из табличной части в качестве ключа обычно указывают уникальную комбинацию полей или скрытое поле-идентификатор. Если этого не сделать, возможны дубли визуального представления строк.
Если наша главная цель — это подбор номенклатуры, которая уже присутствует в существующих заказах, мы можем подойти к задаче с другой стороны. Посмотрим на архитектурную альтернативу:
Справочник.Номенклатура.ЗаказКлиента.Товары) или накладываем отбор, чтобы отсечь те товары, которых нет в заказах.При таком подходе свойство «Основная таблица» будет заполнено корректно, платформа сможет оптимально считывать данные порциями, а ВыбраннаяСтрока сразу будет возвращать готовую ссылку на товар, что значительно упростит программирование обработчиков.
Подводя итог, если вам необходимо выводить табличные части в список — используйте пустую основную таблицу, настраивайте ключевые поля в запросе и извлекайте значения через ДанныеСтроки(). Если же задача позволяет перевернуть логику (отталкиваться от справочника, а не от документа) — смело делайте основную выборку по справочнику с соответствующими фильтрами.