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

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

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

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

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

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

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

Что делает метод Свернуть() и как его вызвать

Метод Свернуть() принимает два строковых параметра: список колонок группировки и список суммируемых колонок. Названия перечисляются через запятую без пробелов или с пробелами — оба варианта допустимы, но опечатка в имени колонки вызовет исключение.

ТЗ.Свернуть("Номенклатура,Склад", "Количество,Сумма");

После выполнения этого кода в таблице останутся только уникальные комбинации «Номенклатура + Склад», а колонки «Количество» и «Сумма» будут содержать итоги по каждой комбинации. Все остальные колонки, не указанные ни в первом, ни во втором параметре, удаляются из таблицы — это важное и часто забываемое следствие.

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

Группировка с суммированием: типовой сценарий

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

// Исходная таблица: Номенклатура, Документ, Количество, Сумма

ТЗИтоги = ТЗОтгрузки.Скопировать();

ТЗИтоги.Свернуть("Номенклатура", "Количество,Сумма");

// Результат: одна строка на товар с суммарными количеством и суммой

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

Порядок действий
  1. 1
    Определите колонки, по которым строки считаются одинаковыми (ключи группировки)
  2. 2
    Определите числовые колонки, которые нужно суммировать
  3. 3
    Сделайте копию таблицы через Скопировать(), если оригинал ещё нужен
  4. 4
    Вызовите Свернуть() с двумя списками колонок
  5. 5
    Проверьте результат: число строк, итоги по суммируемым колонкам

Группировка через запрос: когда Свернуть() недостаточно

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

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

Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;

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

"ВЫБРАТЬ

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

| ТЗ.Количество КАК Количество

|ПОМЕСТИТЬ ВТ_Данные

|ИЗ &ТЗ КАК ТЗ

|;

|ВЫБРАТЬ

| Номенклатура,

| СУММА(Количество) КАК Количество,

| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Номенклатура) КАК ЧислоПозиций

|ИЗ ВТ_Данные

|СГРУППИРОВАТЬ ПО Номенклатура";

Запрос.УстановитьПараметр("ТЗ", ТЗОтгрузки);

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

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

Сравнение подходов к группировке

КритерийСвернуть()Запрос с СГРУППИРОВАТЬ ПО
АгрегатыТолько суммаСумма, среднее, мин/макс, количество, различные
Изменение исходной таблицыДа, разрушаетНет, результат — новая таблица
Фильтрация до группировкиНет, только вручнуюДа, через ГДЕ / ИМЕЮЩИЕ
Скорость на больших объёмахВысокая, в памятиЗависит от объёма, накладные расходы на передачу
Сложность кодаОдна строкаТребуется текст запроса и менеджер ВТ
Маршрут решения

Как выбрать действие

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

Группировка без суммирования и с нестандартными агрегатами

Иногда требуется не сумма, а, например, список документов через запятую по каждому контрагенту. Штатных средств для этого нет: ни Свернуть(), ни агрегатные функции запроса строки не конкатенируют. Задача решается ручным обходом с промежуточным соответствием.

Группы = Новый Соответствие;

Для Каждого Строка Из ТЗ Цикл

Список = Группы.Получить(Строка.Контрагент);

Если Список = Неопределено Тогда

Список = Новый Массив;

Группы.Вставить(Строка.Контрагент, Список);

КонецЕсли;

Список.Добавить(Строка.Документ);

КонецЦикла;

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

При ручной группировке через соответствие ключом может быть только простое значение. Если ключ составной (товар + склад), формируйте строковый ключ вида Строка(Товар.УникальныйИдентификатор()) + "|" + Строка(Склад.УникальныйИдентификатор()) и храните ссылку на исходные значения отдельно.
ПЗ
Практическое замечание

Типичные ошибки при группировке

Самая частая ошибка — потеря колонок: разработчик сворачивает таблицу и затем обращается к колонке, которая не вошла ни в группировку, ни в суммирование. Платформа выдаёт ошибку «Колонка не найдена», и в длинной цепочке вызовов источник проблемы не всегда очевиден.

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

Третья ошибка — ожидание сортировки результата. Метод Свернуть() не гарантирует порядок строк в итоговой таблице. Если порядок важен (например, для вывода в отчёт), после свёртки вызовите Сортировать("Номенклатура") или добавьте УПОРЯДОЧИТЬ ПО в запрос.

Типичные ошибки
01
Свёртка исходной таблицы без копии — детальные данные теряются, последующие этапы алгоритма падают
02
Опечатка в имени колонки в строковом параметре — исключение находят только в рантайме, а не при проверке модуля
03
Суммирование колонки с NULL или нечисловыми значениями — итоги искажаются без явной ошибки
04
Ожидание определённого порядка строк после Свернуть() — порядок не гарантирован, нужна явная сортировка

Как проверить корректность группировки

Надёжный контроль — сверка контрольных итогов до и после группировки. Сумма по суммируемой колонке до свёртки должна совпадать с суммой после неё: группировка объединяет строки, но не должна менять общий итог.

ИтогДо = ТЗ.Итог("Сумма");

ТЗКопия = ТЗ.Скопировать();

ТЗКопия.Свернуть("Номенклатура", "Сумма");

Если ИтогДо <> ТЗКопия.Итог("Сумма") Тогда

ВызватьИсключение "Контрольный итог не сошёлся после свёртки";

КонецЕсли;

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

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

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

Контрольный итог по суммируемой колонке
Норма

Итог до и после свёртки совпадает

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

Итоги различаются — в данных NULL, нечисловые значения или ошибка в списке колонок

Наличие нужных колонок в результате
Норма

Все колонки из обоих параметров доступны

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

Обращение к удалённой колонке вызывает ошибку

Уникальность ключа
Норма

Повторная свёртка по тем же колонкам не меняет число строк

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

Строки сокращаются — группировка не сработала как ожидалось

Итог

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

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

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

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

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

Почему после Свернуть() пропали колонки?

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

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

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

Как сгруппировать строки по нескольким колонкам?

Перечислите колонки через запятую в первом параметре: ТЗ.Свернуть("Организация,Контрагент,Договор", "Сумма"). Строки будут объединяться только при совпадении значений во всех перечисленных колонках одновременно.

Сохраняется ли порядок строк после свёртки?

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

Что делать, если в суммируемой колонке встречаются значения NULL?

При заполнении таблицы из запроса заменяйте NULL через ЕСТЬNULL(Поле, 0) в тексте запроса. Если таблица собрана программно, перед свёрткой пройдите по строкам и приведите пустые значения к нулю — иначе контрольные итоги могут не сойтись.