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