Разработка и Конфигурация · 12 мин
Как свернуть таблицу значений в 1С
Как свернуть таблицу значений в 1С: синтаксис метода Свернуть(), группировка по колонкам, суммирование, типичные ошибки и готовые примеры кода.
Метод Свернуть() таблицы значений — один из самых востребованных инструментов при обработке данных в 1С. Он группирует строки по указанным колонкам и суммирует числовые значения в остальных колонках, превращая детальную таблицу в агрегированную. Типовая задача: есть таблица движений по товарам с полями «Номенклатура», «Склад», «Количество», «Сумма» — нужно получить итоги по каждому товару без детализации по складам.
Разработчики часто путают свертывание с другими способами группировки: запросом с СГРУППИРОВАТЬ ПО, итогами в запросе, сводной таблицей. У каждого подхода своя область применения, и выбор зависит от того, где находятся данные и что нужно получить на выходе. Метод Свернуть() работает только с уже загруженной в память таблицей значений и изменяет её «на месте».
В статье разобран синтаксис метода, поведение при разных комбинациях параметров, типичные ошибки (нечисловые значения, потеря колонок, мутация исходной таблицы) и альтернативы для случаев, когда свертывание не подходит.
Что делает метод Свернуть() и когда он нужен
Свертывание — это группировка строк таблицы значений с агрегацией. Метод анализирует колонки, указанные в первом параметре, находит строки с одинаковыми значениями в этих колонках и объединяет их в одну. Для колонок из второго параметра значения суммируются. Все прочие колонки удаляются — это ключевая особенность, о которой часто забывают.
Типовые сценарии применения:
- получение итогов по номенклатуре из таблицы товаров документа с разбивкой по строкам;
- подсчёт общего количества и суммы по контрагенту из детальных данных о продажах;
- сжатие таблицы движений перед записью в регистр, чтобы убрать дублирующиеся строки;
- агрегация данных, выгруженных из запроса, перед передачей в печатную форму или отчёт.
Важно понимать: метод изменяет саму таблицу, к которой применён, и не возвращает новую. Если исходные данные ещё понадобятся, сначала сделайте копию через ТЗ.Скопировать().
Синтаксис и параметры метода
Метод имеет два параметра, оба — строки с перечислением имён колонок через запятую:
ТаблицаЗначений.Свернуть(КолонкиГруппировки, КолонкиСуммирования);
- КолонкиГруппировки — имена колонок, по которым объединяются строки. Строки с совпадающими значениями во всех перечисленных колонках сольются в одну.
- КолонкиСуммирования — имена числовых колонок, значения которых будут просуммированы внутри каждой группы. Параметр необязательный; если его опустить, таблица просто сожмётся до уникальных комбинаций значений группировочных колонок.
// Исходная таблица: Номенклатура, Склад, Количество, Сумма
ТЗ.Свернуть("Номенклатура", "Количество, Сумма");
// Результат: по одной строке на товар, колонки Склад больше нет
Имена колонок указываются без пробелов внутри имени, разделитель — запятая. Пробелы после запятой допустимы. Если указать несуществующую колонку, платформа вызовет исключение, поэтому при динамическом формировании списков колонок стоит проверять их наличие через ТЗ.Колонки.Найти(ИмяКолонки).
Как ведут себя данные при свертывании
Главное правило: в результирующей таблице остаются только колонки из обоих параметров. Колонка «Склад» из примера выше исчезнет, потому что не входит ни в группировку, ни в суммирование. Если нужно сохранить какое-то значение (например, ставку НДС товара), её придётся либо включить в группировку, либо присоединить обратно после свертывания через соединение с исходными данными.
Суммируемые колонки должны содержать числа. Если в суммируемой колонке встречаются значения других типов (строки, NULL, неопределено), поведение зависит от состава типов: платформа попытается сложить значения, и при несовместимых типах возможна ошибка или непредсказуемый результат. Перед свертыванием таблицы, полученной из запроса, полезно убедиться, что числовые колонки не содержат NULL — в запросе это решается функцией ЕСТЬNULL(Поле, 0).
Порядок строк в результате не гарантирован и не должен использоваться в логике. Если нужен конкретный порядок, после свертывания вызовите ТЗ.Сортировать("Номенклатура").
Практические примеры кода
Свертывание табличной части документа
Классическая задача — получить итоги по товарам из табличной части, где один товар может встречаться в нескольких строках с разными характеристиками или складами:
ТЗ = Документ.Товары.Выгрузить();
ТЗ.Свернуть("Номенклатура", "Количество, Сумма");
Для Каждого Строка Из ТЗ Цикл
Сообщить(Строка(Строка.Номенклатура) + ": " + Строка.Количество);
КонецЦикла;
Метод Выгрузить() табличной части возвращает именно таблицу значений, поэтому свертывание применимо напрямую.
Свертывание копии с сохранением оригинала
ТЗИтоги = ТЗДетальные.Скопировать();
ТЗИтоги.Свернуть("Контрагент, Договор", "СуммаДолга");
// ТЗДетальные осталась нетронутой
Свертывание без суммирования — получение уникальных комбинаций
Если второй параметр опустить, получите аналог SELECT DISTINCT:
ТЗСклады = ТЗДвижения.Скопировать();
ТЗСклады.Свернуть("Склад");
// Одна строка на каждый уникальный склад
ТЗ = Документ.Товары.Выгрузить();
ТЗ.Свернуть("Номенклатура", "Количество, Сумма");
ТЗ.Сортировать("Номенклатура");Частые ошибки при свертывании
Первая и самая массовая ошибка — свертывание исходной таблицы, которая ещё нужна в детальном виде. Симптом: после вызова метода последующий код не находит ожидаемые колонки или строки. Лечится копированием таблицы перед свертыванием.
Вторая ошибка — ожидание, что несуммируемые колонки сохранятся. Разработчик сворачивает по номенклатуре, а потом пытается прочитать из результата единицу измерения или артикул — этих колонок уже нет. Решение: включить такие колонки в группировку (если они однозначны внутри группы) или получать их отдельным соединением.
Третья группа проблем связана с типами данных: суммирование колонки, содержащей NULL из запроса, или колонки составного типа, где встречаются строки. Проверяйте состав типов через ТЗ.Колонки.Найти("Сумма").ТипЗначения и очищайте данные заранее.
Свертывание или запрос: что выбрать
Если данные ещё не загружены из базы, группировку почти всегда эффективнее выполнить запросом с СГРУППИРОВАТЬ ПО и агрегатной функцией СУММА. СУБД выполнит агрегацию быстрее, чем платформа в памяти, и по сети передастся меньше данных.
Метод Свернуть() оправдан, когда таблица уже существует в памяти: выгружена из табличной части, собрана программно, получена из внешнего источника или результата компоновки. Также он удобен для быстрого получения уникальных комбинаций без написания запроса.
| Критерий | Свернуть() | Запрос с ГРУППИРОВАТЬ ПО |
|---|---|---|
| Источник данных | Таблица уже в памяти | Данные в базе |
| Производительность на больших объёмах | Ниже, вся таблица грузится в память | Выше, агрегация на стороне СУБД |
| Агрегатные функции | Только сумма | Сумма, среднее, минимум, максимум, количество |
| Условия отбора | Нет, только постобработка | ГДЕ и ИМЕЮЩИЕ |
Как выбрать подход
Проверка результата свертывания
После свертывания полезно убедиться, что итоги сошлись с исходными данными. Самая надёжная проверка — контрольная сумма: сумма по сворачиваемой колонке до и после операции должна совпадать.
ИтогДо = ТЗ.Итог("Сумма");
ТЗКопия = ТЗ.Скопировать();
ТЗКопия.Свернуть("Номенклатура", "Сумма");
Если ТЗКопия.Итог("Сумма") <> ИтогДо Тогда
// Итоги не сошлись — возможны NULL или нечисловые значения
КонецЕсли;
Дополнительно проверьте количество строк: оно должно равняться числу уникальных комбинаций группировочных колонок. Если строк больше ожидаемого — вероятно, в группировочной колонке есть незаметные различия: лишние пробелы, разный регистр у строковых значений или ссылки на разные объекты с одинаковым представлением.
Как проверить результат
Суммы совпадают
Расхождение — в данных NULL или нечисловые значения
Равно числу уникальных комбинаций группировки
Строк больше — скрытые различия в значениях (пробелы, разные ссылки)
Только колонки группировки и суммирования
Код дальше обращается к удалённым колонкам
Ограничения и альтернативы
Метод умеет только суммировать. Если нужна другая агрегация — среднее, максимум, количество различных — придётся либо уходить в запрос, либо писать ручной обход с соответствием, где ключом будет комбинация группировочных значений, а значением — структура с накапливаемыми показателями.
Для дерева значений метод Свернуть() не применяется к иерархии — он работает только с плоской таблицей. Для сводной аналитики с несколькими измерениями и разными функциями рассмотрите сводную таблицу через СводнаяТаблица в запросе или СКД.
Что важно запомнить
Свернуть(Группировка, Суммирование) объединяет строки и складывает числа, удаляя все прочие колонки и изменяя саму таблицу. Работайте с копией, очищайте NULL до свертывания, проверяйте итоги контрольной суммой. Для данных в базе и нестандартных агрегатов используйте запрос.
Частые вопросы
Почему после Свернуть() пропали колонки?
Это штатное поведение метода: в результате остаются только колонки, перечисленные в параметрах группировки и суммирования. Чтобы сохранить дополнительное поле, включите его в список группировки — при условии, что внутри каждой группы его значение одинаково, иначе группы дробно разобьются.
Можно ли свернуть таблицу по нескольким колонкам одновременно?
Да. Перечислите их через запятую в первом параметре: ТЗ.Свернуть("Контрагент, Договор, Валюта", "Сумма"). Строки объединятся только при совпадении значений во всех перечисленных колонках одновременно.
Что делать, если в суммируемой колонке встречается NULL?
NULL появляется в таблицах, выгруженных из запросов с левыми соединениями. Устраните его на уровне запроса функцией ЕСТЬNULL(Поле, 0) либо пройдитесь по таблице перед свертыванием и замените пустые значения нулём. Иначе сложение может дать ошибку или искажённый итог.
Как получить количество строк в каждой группе при свертывании?
Добавьте в таблицу служебную числовую колонку, заполните её единицами и включите в список суммируемых. После свертывания в этой колонке окажется количество исходных строк, вошедших в каждую группу.
Сохраняется ли порядок строк после свертывания?
Нет, порядок не гарантирован и не должен использоваться в логике программы. Если нужен определённый порядок, вызовите после свертывания метод Сортировать() с указанием нужных колонок и направления.
Чем свертывание отличается от итогов запроса?
Итоги запроса (ИТОГИ ПО) сохраняют детальные строки и добавляют иерархию итоговых записей, а свертывание полностью заменяет таблицу агрегированными строками. Кроме того, запрос выполняется на стороне СУБД и поддерживает разные агрегатные функции, а Свернуть() работает в памяти и умеет только суммировать.