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

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

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

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

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

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

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

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

ВЫБРАТЬ

Товары.Номенклатура,

Товары.Количество,

Товары.Сумма

ИЗ

Документ.РеализацияТоваровУслуг.Товары КАК Товары

ГДЕ

Товары.Ссылка = &Ссылка

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

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

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

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

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Товары.Номенклатура КАК Номенклатура,

| Товары.Количество КАК Количество,

| Товары.Цена КАК Цена,

| Товары.Сумма КАК Сумма

|ИЗ

| Документ.РеализацияТоваровУслуг.Товары КАК Товары

|ГДЕ

| Товары.Ссылка = &Ссылка

|УПОРЯДОЧИТЬ ПО

| Товары.НомерСтроки";

Запрос.УстановитьПараметр("Ссылка", ДокументСсылка);

Результат = Запрос.Выполнить().Выгрузить();

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

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

Выборка по многим документам и соединение с шапкой

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

ВЫБРАТЬ

Товары.Ссылка.Дата КАК Дата,

Товары.Ссылка.Контрагент КАК Контрагент,

Товары.Номенклатура КАК Номенклатура,

Товары.Сумма КАК Сумма

ИЗ

Документ.РеализацияТоваровУслуг.Товары КАК Товары

ГДЕ

Товары.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода

И Товары.Ссылка.Проведен

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

ВЫБРАТЬ

Реализация.Номер КАК Номер,

Товары.Номенклатура КАК Номенклатура,

Товары.Сумма КАК Сумма

ИЗ

Документ.РеализацияТоваровУслуг.Товары КАК Товары

ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг КАК Реализация

ПО Товары.Ссылка = Реализация.Ссылка

ГДЕ

Реализация.Проведен

И Реализация.Контрагент = &Контрагент

Группировка и итоги по строкам табличной части

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

ВЫБРАТЬ

Товары.Номенклатура КАК Номенклатура,

СУММА(Товары.Количество) КАК Количество,

СУММА(Товары.Сумма) КАК Сумма

ИЗ

Документ.РеализацияТоваровУслуг.Товары КАК Товары

ГДЕ

Товары.Ссылка.Проведен

И Товары.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода

СГРУППИРОВАТЬ ПО

Товары.Номенклатура

Правила, которые здесь важно помнить: каждое неагрегатное поле из секции ВЫБРАТЬ должно быть перечислено в СГРУППИРОВАТЬ ПО, иначе запрос не выполнится. Если нужны итоги с детализацией (например, документы внутри номенклатуры), используют ИТОГИ ПО и обход выборки по группировкам.

Для отбора уже сгруппированных значений (например, только позиции с суммой больше порога) применяют секцию ИМЕЮЩИЕ СУММА(Товары.Сумма) > &Порог — обычное ГДЕ к агрегатам неприменимо.

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

Запрос к табличной части справочника и несколько табличных частей

У справочников синтаксис аналогичный: Справочник.Контрагенты.КонтактнаяИнформация. Разница в том, что у справочника вместо даты и проведения фильтруют по ПометкаУдаления и реквизитам владельца.

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

ВЫБРАТЬ

Товары.Ссылка КАК Документ,

Товары.Номенклатура КАК Номенклатура,

Товары.Сумма КАК Сумма

ИЗ

Документ.РеализацияТоваровУслуг.Товары КАК Товары

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ

Услуги.Ссылка,

Услуги.Номенклатура,

Услуги.Сумма

ИЗ

Документ.РеализацияТоваровУслуг.Услуги КАК Услуги

Состав и типы полей в обеих частях объединения должны совпадать по порядку. Если в одной ТЧ нет нужного реквизита, подставляют значение-заглушку, например 0 или NULL, с последующей обработкой.

Способы получить данные табличной части

Запрос к ТЧ

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

Обход коллекции объекта

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

СКД с набором-запросом

Подходит для отчётов пользователям: тот же запрос к ТЧ плюс настройки отбора и оформления без кода.

Типичные ошибки и ограничения

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

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

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

Типичные ошибки
01
Нет фильтра по Проведен — в выборку попадают строки помеченных и черновых документов, итоги завышены
02
Соединение двух ТЧ по ссылке вместо ОБЪЕДИНИТЬ ВСЕ — строки перемножаются, суммы удваиваются и утраиваются
03
Запрос без ограничения периода — полное сканирование таблицы и блокировки на большой базе
04
Обращение к несуществующему реквизиту ТЧ — ошибка исполнения; проверяйте состав реквизитов в конфигураторе

Проверка результата и инструменты отладки

До переноса запроса в код проверьте его в консоли запросов (встроенной в «Инструменты разработчика» или типовую обработку «Консоль запросов» из состава БСП). Сверьте итоговую сумму по выборке с суммой документа — это самый быстрый способ убедиться, что фильтры настроены верно.

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

Контрольные точки

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

Число строк выборки
Норма

Равно числу строк ТЧ в форме документа

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

Строк больше или меньше — проверьте фильтр и соединения

Сумма по выборке
Норма

Совпадает с итогом документа

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

Расхождение — в выборку попали лишние документы или строки перемножились

Время выполнения
Норма

Запрос с фильтром периода выполняется быстро

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

Многократное замедление — нет фильтра, сканируется вся таблица

FAQ

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

Нет, в статическом тексте запроса имя объекта и табличной части указывается явно. Если имя известно только в момент выполнения, текст запроса формируют строкой через подстановку имени, предварительно проверив существование объекта через Метаданные.НайтиПоПолномуИмени().

Как получить табличную часть сразу по нескольким видам документов?

Через ОБЪЕДИНИТЬ ВСЕ: для каждого вида документа пишется свой подзапрос к его табличной части с одинаковым набором полей. Реквизиты, которых нет в части документов, заменяют заглушками (0 или NULL).

Почему в выборке появились строки удалённых документов?

Пометка удаления не удаляет строки табличной части физически. Добавьте условие Товары.Ссылка.Проведен для проведённых документов или НЕ Товары.Ссылка.ПометкаУдаления, если нужны и непроведённые.

Чем отличается поле Ссылка в табличной части от ссылки на строку?

Поле Ссылка — это ссылка на документ-владелец, одинаковая для всех строк ТЧ. Отдельной ссылки на строку не существует: строка идентифицируется парой «Ссылка + НомерСтроки».

Как вывести табличную часть в отчёт на СКД?

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

Итог

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

Табличная часть доступна в запросе как Документ.Имя.ИмяТЧ и связана с шапкой полем Ссылка. Фильтруйте по периоду и признаку Проведен, объединяйте несколько ТЧ через ОБЪЕДИНИТЬ ВСЕ, а результат перед использованием сверяйте с итогами документа.