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

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

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

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

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

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

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

Как работает метод Свернуть()

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

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

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

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

// После вызова колонка Склад удалена,

// строки с одинаковой номенклатурой объединены в одну

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

СвернутаяТаблица = ТаблицаТоваров.Скопировать();

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

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

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

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

ТЗИсходная = Документ.Товары.Выгрузить();

ТЗСвернутая = ТЗИсходная.Скопировать();

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

Обратите внимание: Скопировать() без параметров копирует все строки. Если свёртка нужна только по части данных, сначала отберите строки через НайтиСтроки() или скопируйте с отбором, а затем сворачивайте результат.

Группировка таблицы значений через запрос

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

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

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

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

"ВЫБРАТЬ

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

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

| ТЗ.Сумма КАК Сумма

|ПОМЕСТИТЬ ВТ_Товары

|ИЗ &ТЗ КАК ТЗ

|;

|ВЫБРАТЬ

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

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

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

|ИЗ ВТ_Товары КАК Товары

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

Запрос.УстановитьПараметр("ТЗ", ТаблицаТоваров);

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

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

Сравнение способов группировки

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

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

Метод Свернуть()

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

Запрос с ГРУППИРОВКА ПО

Поддерживает СУММА, МИНИМУМ, МАКСИМУМ, СРЕДНЕЕ, КОЛИЧЕСТВО(РАЗЛИЧНЫЕ), отбор ИМЕЮЩИЕ. Ограничение: больше кода, чувствителен к типам колонок.

СКД (система компоновки данных)

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

Ручной обход с соответствием

Гибкий вариант для нестандартной логики агрегации (например, конкатенация строк). Ограничение: медленнее и требует аккуратного кода.

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

Нестандартная агрегация: обход с соответствием

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

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

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

Данные = Группы.Получить(Строка.Номенклатура);

Если Данные = Неопределено Тогда

Данные = Новый Структура("Количество,Склады", 0, "");

Группы.Вставить(Строка.Номенклатура, Данные);

КонецЕсли;

Данные.Количество = Данные.Количество + Строка.Количество;

Данные.Склады = Данные.Склады + ?(Данные.Склады = "", "", ", ") + Строка.Склад;

КонецЦикла;

Такой подход медленнее встроенных механизмов, поэтому применять его стоит только тогда, когда Свернуть() и запрос задачу не решают.

Типичные ошибки при свёртке

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

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

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

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

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

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

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

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

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

Итог изменился — часть данных потеряна или колонка содержала нечисловые значения

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

Равно числу уникальных комбинаций колонок группировки

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

Строк больше — значит, в группировку не включена колонка, по которой значения различаются

Состав колонок
Норма

Остались только колонки группировок и суммирования

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

Нужная колонка исчезла — её не добавили в параметры метода

СуммаДо = ТаблицаТоваров.Итог("Сумма");

СвернутаяТаблица = ТаблицаТоваров.Скопировать();

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

Если СвернутаяТаблица.Итог("Сумма") <> СуммаДо Тогда

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

КонецЕсли;

Итог

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

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

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

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

Да. Второй параметр метода можно опустить или передать пустую строку: ТЗ.Свернуть("Номенклатура"). Тогда останутся только уникальные комбинации значений колонок группировки — фактически это аналог РАЗЛИЧНЫЕ в запросе.

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

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

Как сгруппировать таблицу и сразу отсортировать результат?

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

Что быстрее: Свернуть() или запрос?

На небольших таблицах разница незаметна. На больших объёмах запрос обычно эффективнее и дополнительно позволяет сразу отфильтровать группы через ИМЕЮЩИЕ. Точный выбор стоит делать замером на реальных данных, если производительность критична.

Как сгруппировать данные для отчёта, чтобы пользователь мог менять группировки?

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

Можно ли свернуть таблицу по части строк?

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