Как объединить вложенные таблицы в запросе 1С и получить плоский список с группировкой?

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

При изучении языка запросов 1С начинающие разработчики часто сталкиваются с ситуацией, когда результат запроса выглядит не как привычная таблица, а как набор строк, где в одной из колонок находится еще одна таблица. Это происходит из-за использования конструкции обращения к табличной части через точку от основного объекта. Рассмотрим подробнее, почему это происходит, в чем заключается проблема и как правильно перестроить запрос для получения корректного результата.

Разбор типичной ошибки: почему возникают вложенные таблицы

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


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

Когда мы пишем Счет.Товары.(...), платформа 1С воспринимает это как команду сформировать вложенную выборку. В итоге результатом запроса будет список документов, где в каждой строке в поле Товары будет лежать объект типа РезультатЗапроса или ВыгрузкаГруппировки. Работать с такими данными крайне неудобно: их нельзя просто так свернуть, отфильтровать по итоговому количеству или использовать для построения сложных отчетов в СКД без лишних манипуляций.

Основные проблемы использования вложенных таблиц:

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

Правильное решение: обращение к табличной части напрямую

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

Рассмотрим правильный синтаксис запроса:


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

Выясним причину, почему этот вариант работает лучше. При обращении к Документ.Счет.Товары платформа 1С на уровне SQL выполняет соединение (JOIN) физической таблицы заголовков документов и таблицы строк этих документов. Каждая строка товара становится отдельной записью в результате запроса. Теперь мы можем свободно использовать секцию СГРУППИРОВАТЬ ПО для объединения одинаковых товаров из разных счетов.

Особенности работы с полями и условиями

При переходе к работе с табличными частями напрямую важно помнить о нескольких правилах работы с реквизитами "шапки" документа и функциями представления.

1. Обращение к реквизитам документа-владельца

Поскольку мы работаем с таблицей Товары, все реквизиты самого документа (Дата, Номер, Контрагент) доступны нам через поле Ссылка. Именно поэтому в условии ГДЕ мы пишем СчетТовары.Ссылка.Дата. Это позволяет эффективно фильтровать строки товаров по свойствам их родительского документа.

2. Использование функции ПРЕДСТАВЛЕНИЕ

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

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

Если ваша задача сложнее, чем простое суммирование (например, нужно объединить товары из Счетов и Реализаций), рекомендуется использовать временные таблицы. Это делает код более читаемым и упрощает отладку. Разберем по шагам, как это сделать:

  1. Помещение данных во временную таблицу: Сначала выберем все нужные строки из табличной части и сохраним их во временном хранилище.
  2. Итоговый запрос: Прочитаем данные из временной таблицы с финальной группировкой.

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


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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ.Номенклатура КАК Номенклатура,
    СУММА(ВТ.Количество) КАК Количество,
    СУММА(ВТ.Сумма) КАК Сумма
ИЗ
    ВТ_ДанныеТоваров КАК ВТ
СГРУППИРОВАТЬ ПО
    ВТ.Номенклатура

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

Рекомендации для начинающих

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

Таким образом, для объединения данных из вложенных структур в одну общую таблицу достаточно сменить объект метаданных в секции ИЗ на таблицу строк документа. Это фундаментальный принцип эффективной разработки на платформе 1С.

← На главную