Разработка и Конфигурация · 11 мин
Как свернуть табличную часть документа в 1С
Как свернуть табличную часть документа в 1С: метод Свернуть(), запрос, ручное группирование строк. Примеры кода, типичные ошибки и проверка результата.
«Свернуть табличную часть» в 1С означает сгруппировать одинаковые строки документа и сложить их числовые показатели: количество, сумму, объём. Типичная ситуация — в реализации попали несколько строк с одной и той же номенклатурой по одинаковой цене, и перед печатью или проведением их нужно объединить в одну строку с общим количеством.
В 1С:Предприятии 8 задача решается тремя основными способами: встроенным методом Свернуть(), запросом с группировкой и ручным обходом строк с поиском дублей. Выбор зависит от того, где выполняется свёртка — на клиенте, на сервере, в модуле объекта — и от того, какие колонки должны участвовать в группировке, а какие — суммироваться.
Ниже разобраны все три подхода с готовым кодом, ограничения каждого метода, проверка результата и типичные ошибки, из-за которых свёртка даёт неверные суммы или «теряет» строки.
Что значит «свернуть» и когда это нужно
Свёртка — это группировка строк табличной части по набору ключевых колонок с суммированием остальных числовых колонок. Например, три строки «Товар А, цена 100, количество 2», «Товар А, цена 100, количество 3» и «Товар Б, цена 50, количество 1» после свёртки по колонкам «Номенклатура, Цена» превращаются в две строки: «Товар А, количество 5» и «Товар Б, количество 1».
Практические сценарии: подготовка данных к печати (покупатель просит без дублей), формирование заказа поставщику из нескольких заявок, консолидация товаров перед подбором на складе, расчёт итогов для отчёта. Важно понимать, что свёртка — операция разрушающая: исходные строки заменяются сгруппированными, и детализация (например, разные серии или склады в строках) теряется, если эти колонки не включены в группировку.
Способ 1: метод Свернуть() — самый быстрый вариант
У таблицы значений и табличной части есть встроенный метод Свернуть(КолонкиГруппировок, КолонкиСуммирования). Он работает на сервере и не требует запросов. Метод изменяет саму таблицу, поэтому обычно сначала делают выгрузку в таблицу значений.
// Выгружаем табличную часть в таблицу значений
ТЗ = Объект.Товары.Выгрузить();
// Сворачиваем по номенклатуре и цене, суммируя количество и сумму
ТЗ.Свернуть("Номенклатура,Цена", "Количество,Сумма");
// Загружаем результат обратно
Объект.Товары.Загрузить(ТЗ);
Первый параметр — строка с именами колонок, по которым определяется «одинаковость» строк. Второй — колонки, значения которых суммируются. Колонки, не перечисленные ни там, ни там, после свёртки будут пустыми — это частая причина «пропавших» данных. Если колонка нужна, но не суммируется (например, единица измерения), включите её в группировку.
Метод Свернуть() недоступен на тонком клиенте для табличной части напрямую в контексте формы — там работают через Выгрузить() в таблицу значений на сервере или используют серверную процедуру формы. В управляемых формах свёртку логично выполнять в серверной процедуре &НаСервере.
ТЗ = Объект.Товары.Выгрузить();
ТЗ.Свернуть("Номенклатура,Цена", "Количество,Сумма,СуммаНДС");
Объект.Товары.Загрузить(ТЗ);Способ 2: свёртка запросом с группировкой
Запрос подходит, когда нужны дополнительные условия: отбор строк, вычисляемые поля, соединение со справочником, сортировка результата. Табличную часть передают в запрос как параметр через временную таблицу.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Товары.Номенклатура КАК Номенклатура,
| Товары.Цена КАК Цена,
| Товары.Количество КАК Количество,
| Товары.Сумма КАК Сумма
|ПОМЕСТИТЬ ВТ_Товары
|ИЗ &Товары КАК Товары
|;
|ВЫБРАТЬ
| ВТ_Товары.Номенклатура КАК Номенклатура,
| ВТ_Товары.Цена КАК Цена,
| СУММА(ВТ_Товары.Количество) КАК Количество,
| СУММА(ВТ_Товары.Сумма) КАК Сумма
|ИЗ ВТ_Товары КАК ВТ_Товары
|СГРУППИРОВАТЬ ПО
| ВТ_Товары.Номенклатура,
| ВТ_Товары.Цена
|УПОРЯДОЧИТЬ ПО
| Номенклатура";
Запрос.УстановитьПараметр("Товары", Объект.Товары.Выгрузить());
Объект.Товары.Загрузить(Запрос.Выполнить().Выгрузить());
Преимущества запроса: можно добавить ГДЕ для исключения строк (например, не сворачивать позиции с нулевой ценой), применить агрегаты МАКСИМУМ, МИНИМУМ, СРЕДНЕЕ вместо суммы, получить дополнительные реквизиты из справочника номенклатуры. Недостаток — больше кода и обращение к СУБД, что при очень частом вызове медленнее метода Свернуть().
Способ 3: ручное группирование строк
Ручной обход нужен, когда правило «одинаковости» сложнее простого равенства колонок: например, объединять строки с разными характеристиками, но одной номенклатурой, и при этом запоминать исходные характеристики в строке через запятую, или пересчитывать цену как средневзвешенную.
СоответствиеСтрок = Новый Соответствие;
НовыеСтроки = Новый Массив;
Для Каждого Строка Из Объект.Товары Цикл
Ключ = Строка(Строка.Номенклатура) + "|" + Формат(Строка.Цена, "ЧГ=");
Найденная = СоответствиеСтрок.Получить(Ключ);
Если Найденная = Неопределено Тогда
СоответствиеСтрок.Вставить(Ключ, Строка);
Иначе
Найденная.Количество = Найденная.Количество + Строка.Количество;
Найденная.Сумма = Найденная.Сумма + Строка.Сумма;
КонецЕсли;
КонецЦикла;
В примере строки-дубли не удаляются физически — нужно либо собрать новую таблицу и загрузить её, либо пометить лишние строки и удалить их обратным циклом (с конца таблицы, чтобы не сбить индексы). Ручной способ даёт полный контроль, но требует аккуратности: цену после сложения сумм обычно пересчитывают как Сумма / Количество, иначе получится рассогласование.
Сравнение способов
Самый короткий код, работает в памяти. Не подходит, если нужны отборы, вычисляемые поля или другие агрегаты кроме суммы.
Гибкие условия, сортировка, агрегаты МАКСИМУМ/СРЕДНЕЕ. Требует обращения к СУБД и больше кода.
Полный контроль над логикой объединения. Больше кода, выше риск ошибок с индексами и пересчётом.
Свёртка на форме документа и на клиенте
В управляемой форме табличная часть — это ДанныеФормыКоллекция, у которой метода Свернуть() нет. Правильный путь — серверная процедура: вызвать РеквизитФормыВЗначение("Объект"), выполнить свёртку методом или запросом, затем ЗначениеВРеквизитФормы(). Либо выгрузить коллекцию через Объект.Товары.Выгрузить() в серверном контексте формы — этот метод доступен, так как объект на сервере представлен прикладным типом.
&НаСервере
Процедура СвернутьТоварыНаСервере()
ТЗ = Объект.Товары.Выгрузить();
ТЗ.Свернуть("Номенклатура,Цена", "Количество,Сумма,СуммаНДС");
Объект.Товары.Загрузить(ТЗ);
КонецПроцедуры
&НаКлиенте
Процедура СвернутьТовары(Команда)
Если Объект.Товары.Количество() = 0 Тогда
Возврат;
КонецЕсли;
СвернутьТоварыНаСервере();
КонецПроцедуры
Для обычных форм (1С 8.2 и ранее) свёртка выполняется напрямую в модуле формы, так как там доступен объект документа целиком. После свёртки на форме полезно вызвать пересчёт итоговых полей в подвале таблицы, если они настроены.
- 1Создайте команду формы и кнопку «Свернуть» в командной панели табличной части
- 2В клиентском обработчике проверьте, что таблица не пуста
- 3Вызовите серверную процедуру: Выгрузить() → Свернуть() → Загрузить()
- 4После свёртки пересчитайте зависимые поля (НДС, итоги) и обновите отображение
- 5Проверьте результат на тестовом документе с известными дублями
Типичные ошибки и как их избежать
Самая частая ошибка — «пропавшие» колонки. Если колонка не указана ни в группировке, ни в суммировании, после Свернуть() она очищается. Единица измерения, ставка НДС, склад — всё, что должно сохраниться, включайте в первый параметр, если значения одинаковы внутри группы.
Вторая ошибка — свёртка без учёта цены или характеристики. Если сгруппировать только по номенклатуре, строки с разными ценами сольются в одну, и сумма перестанет сходиться с ценой × количество. Всегда включайте в ключ группировки все колонки, которые влияют на идентичность строки: цену, характеристику, серию, ставку НДС, склад.
Третья группа проблем — НДС и округление. Сумму НДС нужно либо суммировать отдельной колонкой, либо пересчитывать после свёртки по ставке; простое суммирование корректно, только если ставка включена в группировку. При пересчёте цены из суммы возможны расхождения в копейках из-за округления — задавайте точность через Окр().
Проверка результата свёртки
После свёртки контролируйте три вещи: итоговые суммы не изменились, количество строк уменьшилось ровно на число дублей, ключевые колонки заполнены. Итог по колонке «Сумма» до и после свёртки должен совпасть до копейки — это главный признак корректной операции.
Для проверки дублей удобно выгрузить таблицу и сравнить Выгрузить().Количество() до и после, а также сделать тестовую свёртку копии: если повторная свёртка уже ничего не меняет, значит группировка выполнена полностью.
Как проверить результат
Совпадает с итогом до свёртки
Сумма изменилась — слились строки с разными ценами или потеряны строки
Склад, ставка НДС, единица измерения заполнены
Колонки пустые — их не включили в группировку
Второй вызов Свернуть() не меняет таблицу
Строки снова объединяются — ключ группировки выбран неверно
Сумма НДС сходится с расчётом по ставке
Расхождения в копейках или неверная ставка в строке
FAQ
Можно ли свернуть табличную часть без программирования?
В типовых конфигурациях штатной кнопки «Свернуть» обычно нет. Иногда помогает групповая обработка строк или заполнение документа заново из исходных данных. В остальных случаях свёртку добавляют через расширение или доработку — это небольшая процедура из нескольких строк кода.
Чем Свернуть() отличается от Итог() у таблицы значений?
Итог("Сумма") возвращает одно число — общий итог по колонке, таблица при этом не меняется. Свернуть() изменяет саму таблицу, группируя строки. Для получения итогов по группам без изменения таблицы используют запрос с ИТОГИ ПО.
Как свернуть строки, игнорируя одну колонку, но сохранив её значение?
Стандартный Свернуть() так не умеет: колонка либо в группировке (тогда участвует в сравнении), либо очищается. Варианты: свернуть запросом с агрегатом МАКСИМУМ(Колонка) или МИНИМУМ(Колонка), либо использовать ручной обход и задать своё правило выбора значения.
Работает ли Свернуть() на тонком клиенте?
Для таблицы значений на тонком клиенте метод недоступен — таблица значений вообще не существует в клиентском контексте управляемой формы. Свёртку выполняют в серверной процедуре формы или в модуле объекта, а на клиент возвращают готовый результат.
Как свернуть табличную часть в запросе без выгрузки в параметр?
Если документ уже записан в базу, можно обратиться к его табличной части напрямую: ВЫБРАТЬ ... ИЗ Документ.РеализацияТоваровУслуг.Товары ГДЕ Ссылка = &Ссылка СГРУППИРОВАТЬ ПО .... Для ещё не записанного документа доступен только вариант с передачей таблицы значений параметром.
Что делать, если после свёртки сумма НДС не сходится?
Включите ставку НДС в колонки группировки и суммируйте колонку «СуммаНДС» вместе с «Сумма». Если НДС рассчитывается формулой от суммы, пересчитайте его после свёртки по каждой строке с округлением до двух знаков — суммирование уже округлённых значений часто даёт расхождения в копейках.
Что важно запомнить
Основной инструмент — метод Свернуть("колонки группировки", "суммируемые колонки") применительно к выгруженной таблице значений. Включайте в группировку все колонки, определяющие уникальность строки (цена, ставка НДС, склад), иначе данные потеряются или суммы разойдутся. В управляемой форме свёртку выполняйте на сервере. Контрольный признак корректности — итог по сумме до и после свёртки совпадает.