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

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

Часто при работе с запросами в 1С разработчики сталкиваются с ситуацией, когда использование секции ИТОГИ приводит к формированию избыточной структуры результата. Вместо ожидаемых только итоговых показателей по периодам, система добавляет «детальные записи» — список всех документов, входящих в каждую группу. Разберем, как избавиться от этой лишней детализации и оптимизировать ваш запрос.

Вариант 1: Использование конструкции СГРУППИРОВАТЬ ПО

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

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


ВЫБРАТЬ
    НАЧАЛОПЕРИОДА(ОплатаВзносов.Дата, ДЕНЬ) КАК День,
    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ОплатаВзносов.Ссылка) КАК Документ
ИЗ
    Документ.ОплатаВзносов КАК ОплатаВзносов
ГДЕ
    ОплатаВзносов.ВидОплаты = &ВидОплаты
СГРУППИРОВАТЬ ПО
    НАЧАЛОПЕРИОДА(ОплатаВзносов.Дата, ДЕНЬ)

Почему это решение лучше? При использовании СГРУППИРОВАТЬ ПО сервер базы данных выполняет свертку данных еще до передачи результата в 1С. Это значительно снижает объем данных, передаваемых между сервером и клиентом, и экономит оперативную память, так как структура результата становится плоской, без иерархических уровней.

Вариант 2: Управление обходом результата в коде 1С

Если специфика вашей задачи требует использования именно иерархического запроса (например, когда итоги необходимы для вывода в отчет или для других целей), вы можете ограничить обход результата непосредственно в коде встроенного языка. В этом случае запрос остается неизменным, но мы «учим» 1С игнорировать ненужные записи.

Для этих целей используем метод Выбрать() с указанием параметра ОбходРезультатаЗапроса.ПоГруппировкам. Рассмотрим пример реализации:


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

// Начинаем обход только по группировкам (Дням)
ВыборкаДней = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

Пока ВыборкаДней.Следующий() Цикл
    // Внутри этого цикла мы находимся на уровне «День»
    // Детальные записи (сами документы) сюда не попадают
    Сообщить("Дата: " + ВыборкаДней.День + ", Количество: " + ВыборкаДней.Документ);
    
    // Если бы нам потребовалось зайти в документы, мы бы сделали так:
    // ВыборкаДокументов = ВыборкаДней.Выбрать();
    // Пока ВыборкаДокументов.Следующий() Цикл ... КонецЦикла;
КонецЦикла;

Что важно запомнить при выборе способа решения?

  1. Если ваша задача — только получить цифры (количество, сумма, среднее значение) в разрезе дат, всегда используйте СГРУППИРОВАТЬ ПО. Это стандарт «хорошего тона» в разработке 1С, обеспечивающий высокую производительность.
  2. Если вы используете ИТОГИ, всегда помните о структуре объекта РезультатЗапроса. По умолчанию система обходит дерево результатов «вглубь», переходя от группировок к детальным записям. Чтобы избежать этого, используйте принудительное указание обхода ПоГруппировкам в методе Выбрать().
  3. Если в запросе используются РАЗЛИЧНЫЕ внутри агрегатных функций, помните, что СГРУППИРОВАТЬ ПО работает с ними корректно, позволяя сгруппировать данные по выбранному периоду без потери уникальности ссылок внутри каждой группы.

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

← На главную