К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как обратиться к табличной части в запросе 1С

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

Табличная часть в 1С — это отдельная таблица в базе данных, связанная с объектом-владельцем (документом, справочником) через поле «Ссылка». В запросе к ней обращаются через точку после имени объекта: Документ.РеализацияТоваровУслуг.Товары. Такая конструкция работает как самостоятельный источник данных — её можно выбирать, соединять с другими таблицами, группировать и фильтровать.

Главная сложность для начинающего разработчика — понять, что табличная часть не является «полем» документа. Это полноценная таблица со своими реквизитами и служебными полями (Ссылка, НомерСтроки, КлючСтроки). Поэтому обращение Документ.РеализацияТоваровУслуг.Товары.Номенклатура в списке полей выборки из шапки документа вызовет ошибку — нужно либо выбирать из табличной части напрямую, либо соединять две таблицы.

Базовый синтаксис обращения к табличной части

Имя табличной части формируется по шаблону ТипОбъекта.ИмяОбъекта.ИмяТабличнойЧасти. Например, для табличной части «Товары» документа «ПоступлениеТоваровУслуг» источник данных выглядит так: Документ.ПоступлениеТоваровУслуг.Товары. Для справочника — аналогично: Справочник.Контрагенты.КонтактнаяИнформация.

Простейший запрос к табличной части выглядит так:

bsl
ВЫБРАТЬ
	Товары.Ссылка КАК Документ,
	Товары.Номенклатура КАК Номенклатура,
	Товары.Количество КАК Количество,
	Товары.Сумма КАК Сумма
ИЗ
	Документ.РеализацияТоваровУслуг.Товары КАК Товары
ГДЕ
	Товары.Ссылка = &Ссылка

Псевдоним таблицы (в примере — Товары) задавать не обязательно, но настоятельно рекомендуется: без него обращение к полям идёт через полное имя таблицы, что делает текст запроса громоздким и трудным для сопровождения.

Поле Ссылка в табличной части всегда содержит ссылку на объект-владелец. Через него доступны «через точку» реквизиты шапки: Товары.Ссылка.Дата, Товары.Ссылка.Контрагент. Это удобно для простых случаев, но при больших объёмах данных разыменование через точку может работать медленнее явного соединения — платформа фактически выполняет скрытое соединение с таблицей шапки.

Соединение шапки документа с табличной частью

Когда нужны реквизиты и шапки, и строк, правильный подход — левое или внутреннее соединение двух таблиц по полю Ссылка. Внутреннее соединение вернёт только документы, у которых есть строки; левое — все документы, включая пустые (поля табличной части будут NULL).

bsl
ВЫБРАТЬ
	Реализация.Ссылка КАК Документ,
	Реализация.Контрагент КАК Контрагент,
	Товары.Номенклатура КАК Номенклатура,
	Товары.Количество КАК Количество
ИЗ
	Документ.РеализацияТоваровУслуг КАК Реализация
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг.Товары КАК Товары
		ПО Реализация.Ссылка = Товары.Ссылка
ГДЕ
	Реализация.Проведен
	И Реализация.Дата МЕЖДУ &НачалоПериода И &КонецПериода

Обратите внимание на условие Реализация.Проведен: по умолчанию запрос видит и помеченные на удаление, и непроведённые документы. Если этого не учесть, в отчёт попадут «мусорные» строки, и итоги разойдутся с данными регистров.

Итоги и обход результата по группировкам

Типовая задача — получить документы с их строками для печатной формы или выгрузки. Здесь используется конструкция ИТОГИ ПО с обходом результата по группировкам: сначала выбирается документ, затем вложенная выборка по его строкам.

Порядок действий
  1. 1
    Сформируйте запрос с соединением шапки и табличной части
  2. 2
    Добавьте в конец запроса: ИТОГИ ПО Реализация.Ссылка
  3. 3
    Выполните запрос и обойдите результат методом Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам)
  4. 4
    Для каждой строки группировки вызовите вложенную Выбрать() — получите строки табличной части
  5. 5
    Проверьте, что количество вложенных строк совпадает с числом строк в документе

Пример обхода в коде модуля:

bsl
ВыборкаДокументы = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаДокументы.Следующий() Цикл
	ВыборкаСтроки = ВыборкаДокументы.Выбрать();
	Пока ВыборкаСтроки.Следующий() Цикл
		// Обработка строки табличной части
	КонецЦикла;
КонецЦикла;

Альтернатива — выгрузить результат в таблицу значений методом Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам): тогда строки табличной части окажутся в колонке-коллекции «Строки», что удобно для дальнейшей программной обработки.

Группировка и агрегирование данных табличной части

Для аналитических задач табличную часть группируют по нужным измерениям с агрегатными функциями СУММА, КОЛИЧЕСТВО, МАКСИМУМ. Например, продажи по номенклатуре за период:

bsl
ВЫБРАТЬ
	Товары.Номенклатура КАК Номенклатура,
	СУММА(Товары.Количество) КАК Количество,
	СУММА(Товары.Сумма) КАК Сумма
ИЗ
	Документ.РеализацияТоваровУслуг.Товары КАК Товары
ГДЕ
	Товары.Ссылка.Проведен
	И Товары.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода
СГРУППИРОВАТЬ ПО
	Товары.Номенклатура

Конструкция КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Товары.Ссылка) позволяет посчитать, в скольких документах встречается позиция — полезно при анализе ассортимента. Учтите, что обычное КОЛИЧЕСТВО посчитает строки, а не документы.

Виртуальная таблица или табличная часть: что выбрать

Часто те же данные доступны и через регистры (например, продажи — через регистр накопления «Продажи»). Выбор источника влияет и на скорость, и на корректность результата.

Сравнение вариантов

Запрос к табличной части

Подходит для печатных форм, выгрузок состава документа, проверки заполнения строк. Даёт точный состав документов, включая непроведённые. Медленнее регистров на агрегатных отчётах.

Виртуальная таблица регистра

Подходит для оборотов, остатков, аналитики за период. Быстрее за счёт предрасчитанных итогов, но содержит только проведённые документы и только те измерения, что заложены в регистр.

Обращение из кода (ДокументОбъект.Товары)

Подходит, когда нужно изменить строки или прочитать один-два документа. Для массового чтения данных запрос эффективнее.

Правило простое: нужен состав конкретных документов — берите табличную часть; нужны итоги за период — идите в регистр; нужно менять данные — работайте с объектом.

Типичные ошибки при работе с табличными частями

Типичные ошибки
01
Обращение к табличной части как к полю шапки (Документ.Реализация.Товары в списке полей выборки из шапки) — синтаксическая ошибка, табличная часть является отдельным источником данных
02
Соединение с двумя табличными частями одновременно — строки перемножаются, суммы задваиваются и завышаются
03
Отсутствие отбора по Проведен — в отчёт попадают непроведённые и помеченные на удаление документы
04
Использование разыменования Товары.Ссылка.Контрагент в условиях и соединениях на больших объёмах — лишние неявные соединения замедляют запрос
05
Забытый псевдоним таблицы в сложном запросе — неоднозначность имён полей и ошибки исполнения
Контрольные точки

Как проверить результат

Количество строк результата
Норма

Совпадает с суммой строк табличных частей отобранных документов

Тревожный признак

Строк больше — вероятно декартово произведение из-за второго соединения

Итоговая сумма по документу
Норма

Равна сумме по табличной части, видимой в форме документа

Тревожный признак

Сумма кратно завышена — документ попал в выборку несколько раз

Состав документов
Норма

Только проведённые документы за заданный период

Тревожный признак

Присутствуют помеченные на удаление или документы вне периода

Особенности и ограничения

У табличных частей есть служебное поле НомерСтроки — по нему можно упорядочить результат в том же порядке, в каком строки идут в документе: УПОРЯДОЧИТЬ ПО Товары.Ссылка, Товары.НомерСтроки. Без явного упорядочивания порядок строк не гарантирован.

В запросах с компоновкой данных (СКД) табличные части работают так же, но помните про роли полей и доступность в настройках: если поле табличной части не выведено в набор данных, пользователь отчёта не сможет его выбрать. Для внешних отчётов проверяйте, что имя табличной части в запросе совпадает с именем в метаданных конфигурации — в типовых решениях имена могут отличаться от привычных («Товары», «Услуги», «Серии»).

Для табличных частей справочников логика идентична: Справочник.Номенклатура.ДополнительныеРеквизиты — это таблица, связанная с элементом справочника полем Ссылка. Частый сценарий — поиск элементов по значению дополнительного реквизита через соединение с этой табличной частью.

Итог

Что важно запомнить

Табличная часть — отдельная таблица, доступная по шаблону Объект.Имя.ТабличнаяЧасть и связанная с шапкой полем Ссылка. Для состава документов используйте соединение и итоги по группировкам, для аналитики — регистры, всегда фильтруйте по проведённости и периоду.

Частые вопросы

Можно ли обратиться к табличной части без указания документа-владельца?

Нет. Табличная часть не существует отдельно от объекта-владельца: в запросе она всегда указывается полным путём через тип и имя объекта. Получить «все табличные части Товары всех документов» одним источником нельзя — нужно перечислить конкретные документы и объединить выборки через ОБЪЕДИНИТЬ ВСЕ.

Как получить строки табличной части одного конкретного документа?

Передайте ссылку параметром и поставьте условие ГДЕ Товары.Ссылка = &Ссылка. Это самый быстрый вариант: платформа выберет строки по индексу поля Ссылка без полного сканирования таблицы.

Почему суммы в запросе задваиваются?

Чаще всего причина — соединение с двумя табличными частями одного документа или с таблицей, где документу соответствует несколько записей. Каждая строка первой таблицы перемножается на каждую строку второй. Решение — разделить данные на отдельные запросы или временные таблицы и соединять уже агрегированные результаты.

Чем отличается обращение к табличной части в запросе и в коде через объект?

В коде ДокументОбъект.Товары — это коллекция строк в памяти, доступная для изменения, но требующая получения всего объекта. В запросе табличная часть — источник данных только для чтения, зато позволяющий обработать тысячи документов одним обращением к базе. Для массового чтения используйте запрос, для изменения — объект.

Как вывести строки табличной части в том же порядке, что в документе?

Добавьте упорядочивание по служебному полю НомерСтроки: УПОРЯДОЧИТЬ ПО Товары.Ссылка, Товары.НомерСтроки. Без этого порядок строк в результате запроса не гарантирован и может отличаться от порядка в форме документа.

Работает ли обращение к табличной части в СКД и динамических списках?

В СКД — да, табличная часть доступна как обычный источник в наборе данных. В динамических списках произвольный запрос к табличным частям тоже возможен, но для основной таблицы списка есть ограничения: если табличная часть выбрана основной таблицей, список покажет строки, а не документы, что редко бывает нужно.