Разработка и Конфигурация · 12 мин
Как свернуть таблицу значений в 1С
Как свернуть таблицу значений в 1С: метод Свернуть, группировка измерений и суммирование ресурсов, типичные ошибки, свёртка через запрос и проверка результата.
Свёртка таблицы значений — одна из самых частых операций при программной обработке данных в 1С. Задача возникает, когда в таблице есть несколько строк с одинаковыми значениями в ключевых колонках (например, один и тот же товар встречается в нескольких строках документа), а нужно получить по одной строке на каждую комбинацию с суммированием числовых показателей.
Для этого во встроенном языке 1С существует метод Свернуть() объекта «ТаблицаЗначений». Он группирует строки по указанным колонкам-измерениям и суммирует значения в колонках-ресурсах. Метод прост в вызове, но у него есть особенности: он изменяет исходную таблицу, удаляет неуказанные колонки и суммирует только числовые значения.
Ниже разобран синтаксис метода, типовые сценарии использования, альтернатива через запрос, а также ошибки, которые чаще всего допускают разработчики при свёртке.
Что делает метод Свернуть и когда он нужен
Метод Свернуть() объединяет строки таблицы значений, у которых совпадают значения в колонках группировки. Для каждой уникальной комбинации остаётся одна строка, а значения в колонках суммирования складываются. Это аналог конструкции GROUP BY с агрегатной функцией SUM в SQL.
Типовые ситуации, где свёртка необходима:
- консолидация табличной части документа, где один товар введён несколькими строками;
- подготовка данных для печатной формы или выгрузки, где дубли недопустимы;
- агрегация данных перед расчётом итогов, сравнением или проведением;
- объединение данных из нескольких источников в одну сводную таблицу.
Важно понимать: свёртка — это разрушающая операция. Все колонки, которые не указаны ни в группировке, ни в суммировании, будут удалены из таблицы вместе с данными. Поэтому перед вызовом метода нужно чётко решить, какие данные должны остаться.
Синтаксис и параметры метода Свернуть
Метод имеет два параметра, оба — строки с именами колонок через запятую:
ТаблицаЗначений.Свернуть(КолонкиГруппировки, КолонкиСуммирования);
- КолонкиГруппировки — имена колонок, по которым выполняется группировка. Обязательный параметр.
- КолонкиСуммирования — имена числовых колонок, значения которых суммируются. Необязательный параметр.
Пример: есть таблица с колонками «Номенклатура», «Склад», «Количество», «Сумма». Нужно получить итоги по каждой номенклатуре независимо от склада:
ТЗ.Свернуть("Номенклатура", "Количество,Сумма");
После выполнения в таблице останутся только колонки «Номенклатура», «Количество» и «Сумма». Колонка «Склад» будет удалена, а строки с одинаковой номенклатурой объединятся в одну с суммированными значениями.
// Исходная таблица: Номенклатура, Склад, Количество, Сумма
КопияТЗ = ТЗ.Скопировать(); // сохраняем исходник
КопияТЗ.Свернуть("Номенклатура", "Количество,Сумма");
// В КопияТЗ — по одной строке на номенклатуру с итогамиЕсли второй параметр не указан, метод просто удалит дублирующиеся строки по колонкам группировки, оставив по одной строке на каждую комбинацию. Значения в остальных колонках при этом будут потеряны, поскольку сами колонки удаляются.
Типовые сценарии свёртки
Свёртка по одной колонке с суммированием
Самый частый случай — свести табличную часть по товару. Например, при загрузке данных из файла один и тот же артикул встречается в нескольких строках, а для дальнейшей обработки нужна одна строка с общим количеством:
ТЗ.Свернуть("Артикул", "Количество,Цена,Сумма");
Здесь важно, чтобы колонки суммирования имели числовой тип. Если колонка «Цена» содержит строки, суммирование даст некорректный результат или нули.
Свёртка по нескольким колонкам
Когда нужна детализация, например, по товару и складу одновременно, колонки группировки перечисляются через запятую:
ТЗ.Свернуть("Номенклатура,Склад,Характеристика", "Количество");
Чем больше колонок в группировке, тем детальнее результат и тем меньше строк будет объединено. Порядок перечисления колонок на результат группировки не влияет, но влияет на порядок колонок в итоговой таблице.
Свёртка без суммирования (удаление дублей)
Если задача — просто получить список уникальных комбинаций, второй параметр опускается:
ТЗ.Свернуть("Контрагент,Договор");
После такого вызова в таблице останутся только две эти колонки без повторяющихся пар значений. Это удобный способ быстро получить, например, перечень уникальных контрагентов из большой выборки.
- 1Проверьте, что колонки суммирования имеют числовой тип значений
- 2Создайте копию таблицы через Скопировать(), если исходные данные ещё нужны
- 3Вызовите Свернуть() с перечнем колонок группировки и суммирования
- 4Проверьте результат: число строк, итоги по суммируемым колонкам
- 5Сравните общий итог до и после свёртки — суммы должны совпадать
Особенности и ограничения метода
Первая особенность — метод изменяет саму таблицу, для которой вызван, и ничего не возвращает. Если исходная таблица понадобится позже (например, для детального протокола), предварительно сохраните её копию методом Скопировать().
Вторая особенность — суммируются только значения числового типа. Если в колонке суммирования встречаются NULL, строки или значения других типов, они будут проигнорированы или приведут к неожиданным итогам. Перед свёрткой стоит убедиться, что колонка заполнена корректно, при необходимости — пройтись по таблице и заменить нечисловые значения на 0.
Третья особенность — сравнение значений при группировке выполняется строго. Строки «Товар1 » с пробелом и «Товар1» без пробела — это разные значения, и они не сгруппируются. То же касается ссылок: ссылки на разные объекты с одинаковым наименованием считаются разными значениями. Если данные приходят из внешних источников, имеет смысл предварительно нормализовать строковые поля (обрезать пробелы через СокрЛП()).
Альтернатива: свёртка через запрос
Если данные ещё не выбраны из базы или таблица значений получена из СУБД, часто эффективнее выполнить группировку запросом, а не методом Свернуть(). Запрос с GROUP BY и SUM выполняется на сервере СУБД и, как правило, быстрее обрабатывает большие объёмы, чем построчная свёртка в памяти.
Кроме того, запрос позволяет использовать другие агрегатные функции — МАКСИМУМ, МИНИМУМ, СРЕДНЕЕ, КОЛИЧЕСТВО, — чего метод Свернуть() не умеет: он только суммирует. Если нужна, например, максимальная цена по товару, свёртка не подойдёт, а запрос решит задачу одной конструкцией.
Таблицу значений можно передать в запрос как временную таблицу через менеджер временных таблиц и затем сгруппировать её средствами запроса. Это разумный вариант, когда таблица уже собрана программно, но требуется нестандартная агрегация.
Сравнение подходов
Подходит для уже готовой таблицы в памяти и простого суммирования. Ограничение: только сумма, удаляет лишние колонки, изменяет исходную таблицу.
Подходит для больших объёмов и нестандартной агрегации (максимум, количество, среднее). Требует написания текста запроса и, для таблицы значений, помещения её во временную таблицу.
Подходит, когда логика объединения строк сложнее суммирования (конкатенация строк, условное объединение). Самый трудоёмкий и медленный вариант, применять только при реальной необходимости.
Проверка результата и типичные ошибки
После свёртки обязательно проверьте результат, особенно если операция выполняется в фоновом задании или обработке, где ошибка заметна не сразу. Базовый контроль — сравнение итогов: сумма по колонке «Сумма» до свёртки должна равняться сумме после свёртки. Если итоги разошлись, ищите причину в типах данных или в нечисловых значениях.
Полезно также проверить количество строк: оно должно быть не больше, чем до свёртки, и соответствовать числу уникальных комбинаций колонок группировки. Если строк столько же, сколько было, значит, группировка фактически не сработала — например, из-за скрытых различий в значениях (пробелы, регистр не влияет, а вот невидимые символы — влияют).
Как проверить результат свёртки
Итоги совпадают
Итог уменьшился — часть значений нечисловая или потеряна
Строк стало меньше или столько же
Строк столько же — значения группировки различаются (пробелы, разные ссылки)
Остались только колонки группировки и суммирования
Нужная колонка исчезла — её не включили в параметры метода
Разберём ошибки, которые допускают чаще всего. Первая — свёртка исходной таблицы без копии, после чего детальные данные безвозвратно теряются, а код ниже по алгоритму пытается обратиться к удалённым колонкам и падает с ошибкой «Поле не обнаружено». Вторая — попытка суммировать нечисловую колонку: метод отработает без исключения, но результат будет нулевым или неполным, и ошибка всплывёт только на этапе анализа итогов.
Третья распространённая ошибка — свёртка с лишними колонками в группировке. Например, разработчик включает в группировку колонку «Комментарий», значения в которой уникальны почти для каждой строки. В результате строки не объединяются, и разработчик ошибочно считает, что метод «не работает». Четвёртая — свёртка табличной части документа напрямую с последующей попыткой записи: документ теряет обязательные колонки и либо не записывается, либо записывается с потерянными данными.
Производительность и большие таблицы
Для таблиц в несколько тысяч строк метод Свернуть() отрабатывает быстро, и о производительности можно не думать. Но при объёмах в сотни тысяч строк свёртка в памяти может стать заметной по времени, особенно если она выполняется в цикле или внутри обработки большого пакета данных.
В таких случаях рассмотрите варианты оптимизации: группировку на уровне запроса ещё до формирования таблицы, уменьшение числа колонок до свёртки (чем меньше данных, тем быстрее сравнение строк), а также отказ от повторных свёрток одной и той же таблицы — результат можно один раз сохранить и переиспользовать.
FAQ по свёртке таблиц значений
Можно ли свернуть таблицу, не удаляя остальные колонки?
Штатный метод Свернуть() удаляет все колонки, не указанные в параметрах. Если нужны другие колонки, либо включите их в группировку, либо используйте запрос с группировкой, где для несуммируемых полей можно применить МАКСИМУМ или МИНИМУМ, либо реализуйте группировку вручную в цикле.
Что происходит со значением NULL при суммировании?
Значения NULL при суммировании игнорируются — они не прибавляются к итогу. Если все значения в группе равны NULL, итог может оказаться нулевым или неопределённым в зависимости от состава данных. Перед свёрткой имеет смысл заменить NULL на 0, если нулевое значение допустимо по логике задачи.
Как свернуть таблицу и получить количество строк в каждой группе?
Метод Свернуть() умеет только суммировать, поэтому приём такой: добавьте в таблицу вспомогательную числовую колонку, заполните её единицами и включите в колонки суммирования. После свёртки в этой колонке окажется количество исходных строк в каждой группе.
Почему после свёртки остались дубли, хотя значения выглядят одинаково?
Чаще всего причина в неочевидных различиях: пробелы в начале или конце строк, неразрывные пробелы, разный регистр не играет роли, а вот разные типы значений (строка против ссылки) или разные ссылки с одинаковым наименованием — играют. Нормализуйте строки через СокрЛП() и проверьте типы колонок перед свёрткой.
Можно ли свернуть дерево значений?
Метода Свернуть() у объекта «ДеревоЗначений» нет. Если нужна группировка, данные обычно выгружают в таблицу значений, сворачивают её и при необходимости строят дерево заново. Либо группировку выполняют запросом с итогами по иерархии.
Влияет ли порядок колонок в параметрах на результат?
На состав групп — нет: комбинации значений группируются независимо от порядка перечисления колонок. Но порядок влияет на расположение колонок в итоговой таблице: сначала идут колонки группировки в указанном порядке, затем колонки суммирования.
Что важно запомнить
Метод Свернуть(Группировка, Суммирование) группирует строки и суммирует числовые колонки, при этом изменяет исходную таблицу и удаляет неуказанные колонки. Перед вызовом делайте копию таблицы, проверяйте числовые типы и нормализуйте строки; после — сверяйте итоги до и после. Для нестандартной агрегации и больших объёмов используйте запрос с группировкой.