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

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

Как сгруппировать табличную часть документа в 1С

Как сгруппировать табличную часть документа в 1С: свёртка по колонкам, запрос с СГРУППИРОВАТЬ ПО, итоги по строкам. Примеры кода, ошибки и проверка результата.

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

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

Ниже разобраны рабочие варианты с примерами кода, условиями применения и типичными ошибками. Примеры приведены на встроенном языке 1С и применимы как к управляемым, так и к обычным формам, с оговорками по контексту выполнения.

Что значит «сгруппировать» табличную часть и когда это нужно

Под группировкой понимают объединение нескольких строк табличной части по совпадающим значениям одной или нескольких колонок с суммированием (или иной агрегацией) числовых колонок. Например, в документе «Реализация товаров и услуг» одна и та же номенклатура встречается пять раз с разным количеством — после группировки останется одна строка с общим количеством и общей суммой.

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

Способ 1: метод Свернуть() таблицы значений

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

ТЗ = Объект.Товары.Выгрузить();

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

// Теперь в ТЗ по одной строке на каждую номенклатуру

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

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

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

Способ 2: запрос с СГРУППИРОВАТЬ ПО

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

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

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

"ВЫБРАТЬ

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

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

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

|ИЗ

| Документ.РеализацияТоваровУслуг.Товары КАК Товары

|ГДЕ

| Товары.Ссылка = &Ссылка

|СГРУППИРОВАТЬ ПО

| Товары.Номенклатура";

Запрос.УстановитьПараметр("Ссылка", ДокументСсылка);

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

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

Способ 3: итоги через ИТОГИ ПО и обход выборки

Когда нужна не свёртка в одну строку, а иерархия «группа — строки внутри группы» (например, для печатной формы с подзаголовками по складам), подходит конструкция ИТОГИ ПО. Запрос формирует дерево: итоговые записи по группам и детальные записи внутри них.

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

"ВЫБРАТЬ

| Товары.Склад КАК Склад,

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

| Товары.Количество КАК Количество

|ИЗ

| Документ.ПеремещениеТоваров.Товары КАК Товары

|ГДЕ

| Товары.Ссылка = &Ссылка

|ИТОГИ

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

|ПО

| Склад";

ВыборкаСклады = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

Пока ВыборкаСклады.Следующий() Цикл

// Итог по складу

Детали = ВыборкаСклады.Выбрать();

Пока Детали.Следующий() Цикл

// Строки внутри склада

КонецЦикла;

КонецЦикла;

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

Сравнение способов и критерии выбора

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

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

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

Свернуть()

Быстрый и простой, работает с данными формы. Ограничение: только суммирование, нет отборов и соединений.

СГРУППИРОВАТЬ ПО

Гибкие отборы и соединения, агрегаты СУММА, МАКСИМУМ, СРЕДНЕЕ. Ограничение: только сервер, не видит несохранённые данные.

ИТОГИ ПО

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

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

Главный контроль — сравнение итогов до и после свёртки. Сумма по колонке «Количество» и «Сумма» исходной табличной части должна точно совпасть с суммой сгруппированной таблицы. Расхождение означает, что часть строк потеряна: например, не все суммируемые колонки перечислены в ресурсах, или в группировку попали строки с пустыми значениями ключевых колонок, которые объединились в одну строку с пустым ключом.

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

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

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

Итог по сумме и количеству
Норма

Совпадает с итогом исходной табличной части

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

Сумма изменилась — потеряны строки или колонки

Число строк после свёртки
Норма

Равно числу уникальных комбинаций ключей

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

Строк столько же, сколько было — ключ выбран неверно

Строки с пустым ключом
Норма

Пустых номенклатур нет или они обработаны отдельно

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

Появилась строка с пустой номенклатурой и большой суммой

Типичные ошибки и ограничения

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

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

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

Типичные ошибки
01
Не включили все суммируемые колонки в ресурсы — итоги по забытой колонке потеряны
02
Свернули по номенклатуре без ставки НДС — строки с разными ставками объединились, расчёт налога искажён
03
Загрузили свёрнутую таблицу обратно в документ без проверки колонок — данные табличной части испорчены
04
Группировали по наименованию вместо ссылки — разные элементы справочника склеились
05
Использовали запрос к несохранённому документу — получили устаревшие данные из базы

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

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

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

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

В запросе добавьте агрегат КОЛИЧЕСТВО(*) с группировкой по нужному полю. При свёртке таблицы значений добавьте вспомогательную числовую колонку со значением 1 в каждой строке и включите её в ресурсы — после Свернуть() в ней будет число объединённых строк.

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

Метод удаляет все колонки, не указанные ни в параметре измерений, ни в параметре ресурсов. Перечислите нужные колонки явно: ключевые — в первом параметре, суммируемые — во втором. Нечисловые колонки, которые нельзя суммировать, сохранить можно только включив их в измерения.

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

Используйте запрос с условием ГДЕ Ссылка В (&СписокДокументов) и группировкой по нужным полям. Параметру передайте массив или список значений со ссылками на документы. Метод Свернуть() для этого не подходит — он работает только с одной выгруженной таблицей.

Работает ли Свернуть() на тонком клиенте?

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

Как сгруппировать строки, но сохранить порядок сортировки?

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

Итог

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

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