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

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

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

Как свернуть табличную часть документа в 1С: метод Свернуть(), запрос, ручное группирование строк. Примеры кода, типичные ошибки и проверка результата.

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

В 1С:Предприятии 8 задача решается тремя основными способами: встроенным методом Свернуть(), запросом с группировкой и ручным обходом строк с поиском дублей. Выбор зависит от того, где выполняется свёртка — на клиенте, на сервере, в модуле объекта — и от того, какие колонки должны участвовать в группировке, а какие — суммироваться.

Ниже разобраны все три подхода с готовым кодом, ограничения каждого метода, проверка результата и типичные ошибки, из-за которых свёртка даёт неверные суммы или «теряет» строки.

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

Свёртка — это группировка строк табличной части по набору ключевых колонок с суммированием остальных числовых колонок. Например, три строки «Товар А, цена 100, количество 2», «Товар А, цена 100, количество 3» и «Товар Б, цена 50, количество 1» после свёртки по колонкам «Номенклатура, Цена» превращаются в две строки: «Товар А, количество 5» и «Товар Б, количество 1».

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

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

У таблицы значений и табличной части есть встроенный метод Свернуть(КолонкиГруппировок, КолонкиСуммирования). Он работает на сервере и не требует запросов. Метод изменяет саму таблицу, поэтому обычно сначала делают выгрузку в таблицу значений.

// Выгружаем табличную часть в таблицу значений

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

// Сворачиваем по номенклатуре и цене, суммируя количество и сумму

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

// Загружаем результат обратно

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

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

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

bsl
ТЗ = Объект.Товары.Выгрузить();
ТЗ.Свернуть("Номенклатура,Цена", "Количество,Сумма,СуммаНДС");
Объект.Товары.Загрузить(ТЗ);

Способ 2: свёртка запросом с группировкой

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

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

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

"ВЫБРАТЬ

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

| Товары.Цена КАК Цена,

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

| Товары.Сумма КАК Сумма

|ПОМЕСТИТЬ ВТ_Товары

|ИЗ &Товары КАК Товары

|;

|ВЫБРАТЬ

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

| ВТ_Товары.Цена КАК Цена,

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

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

|ИЗ ВТ_Товары КАК ВТ_Товары

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

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

| ВТ_Товары.Цена

|УПОРЯДОЧИТЬ ПО

| Номенклатура";

Запрос.УстановитьПараметр("Товары", Объект.Товары.Выгрузить());

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

Преимущества запроса: можно добавить ГДЕ для исключения строк (например, не сворачивать позиции с нулевой ценой), применить агрегаты МАКСИМУМ, МИНИМУМ, СРЕДНЕЕ вместо суммы, получить дополнительные реквизиты из справочника номенклатуры. Недостаток — больше кода и обращение к СУБД, что при очень частом вызове медленнее метода Свернуть().

Способ 3: ручное группирование строк

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

СоответствиеСтрок = Новый Соответствие;

НовыеСтроки = Новый Массив;

Для Каждого Строка Из Объект.Товары Цикл

Ключ = Строка(Строка.Номенклатура) + "|" + Формат(Строка.Цена, "ЧГ=");

Найденная = СоответствиеСтрок.Получить(Ключ);

Если Найденная = Неопределено Тогда

СоответствиеСтрок.Вставить(Ключ, Строка);

Иначе

Найденная.Количество = Найденная.Количество + Строка.Количество;

Найденная.Сумма = Найденная.Сумма + Строка.Сумма;

КонецЕсли;

КонецЦикла;

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

Сравнение способов

Метод Свернуть()

Самый короткий код, работает в памяти. Не подходит, если нужны отборы, вычисляемые поля или другие агрегаты кроме суммы.

Запрос с группировкой

Гибкие условия, сортировка, агрегаты МАКСИМУМ/СРЕДНЕЕ. Требует обращения к СУБД и больше кода.

Ручной обход

Полный контроль над логикой объединения. Больше кода, выше риск ошибок с индексами и пересчётом.

Свёртка на форме документа и на клиенте

В управляемой форме табличная часть — это ДанныеФормыКоллекция, у которой метода Свернуть() нет. Правильный путь — серверная процедура: вызвать РеквизитФормыВЗначение("Объект"), выполнить свёртку методом или запросом, затем ЗначениеВРеквизитФормы(). Либо выгрузить коллекцию через Объект.Товары.Выгрузить() в серверном контексте формы — этот метод доступен, так как объект на сервере представлен прикладным типом.

&НаСервере

Процедура СвернутьТоварыНаСервере()

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

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

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

КонецПроцедуры

&НаКлиенте

Процедура СвернутьТовары(Команда)

Если Объект.Товары.Количество() = 0 Тогда

Возврат;

КонецЕсли;

СвернутьТоварыНаСервере();

КонецПроцедуры

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

Порядок действий в управляемой форме
  1. 1
    Создайте команду формы и кнопку «Свернуть» в командной панели табличной части
  2. 2
    В клиентском обработчике проверьте, что таблица не пуста
  3. 3
    Вызовите серверную процедуру: Выгрузить() → Свернуть() → Загрузить()
  4. 4
    После свёртки пересчитайте зависимые поля (НДС, итоги) и обновите отображение
  5. 5
    Проверьте результат на тестовом документе с известными дублями

Типичные ошибки и как их избежать

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

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

Третья группа проблем — НДС и округление. Сумму НДС нужно либо суммировать отдельной колонкой, либо пересчитывать после свёртки по ставке; простое суммирование корректно, только если ставка включена в группировку. При пересчёте цены из суммы возможны расхождения в копейках из-за округления — задавайте точность через Окр().

Типичные ошибки
01
Не включили колонку в группировку — после Свернуть() она стала пустой (склад, ставка НДС, единица измерения)
02
Свернули только по номенклатуре — слились строки с разными ценами, сумма не сходится с ценой × количество
03
Удалили строки в прямом цикле — индексы сбились, часть дублей пропущена
04
Свернули табличную часть объекта до записи и потеряли исходную детализацию — делайте копию через Выгрузить()
05
Попытались вызвать Свернуть() на клиенте для ДанныеФормыКоллекция — метод недоступен, нужна серверная процедура

Проверка результата свёртки

После свёртки контролируйте три вещи: итоговые суммы не изменились, количество строк уменьшилось ровно на число дублей, ключевые колонки заполнены. Итог по колонке «Сумма» до и после свёртки должен совпасть до копейки — это главный признак корректной операции.

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

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

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

Итог по колонке «Сумма»
Норма

Совпадает с итогом до свёртки

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

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

Заполненность колонок
Норма

Склад, ставка НДС, единица измерения заполнены

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

Колонки пустые — их не включили в группировку

Повторная свёртка
Норма

Второй вызов Свернуть() не меняет таблицу

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

Строки снова объединяются — ключ группировки выбран неверно

НДС
Норма

Сумма НДС сходится с расчётом по ставке

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

Расхождения в копейках или неверная ставка в строке

FAQ

Можно ли свернуть табличную часть без программирования?

В типовых конфигурациях штатной кнопки «Свернуть» обычно нет. Иногда помогает групповая обработка строк или заполнение документа заново из исходных данных. В остальных случаях свёртку добавляют через расширение или доработку — это небольшая процедура из нескольких строк кода.

Чем Свернуть() отличается от Итог() у таблицы значений?

Итог("Сумма") возвращает одно число — общий итог по колонке, таблица при этом не меняется. Свернуть() изменяет саму таблицу, группируя строки. Для получения итогов по группам без изменения таблицы используют запрос с ИТОГИ ПО.

Как свернуть строки, игнорируя одну колонку, но сохранив её значение?

Стандартный Свернуть() так не умеет: колонка либо в группировке (тогда участвует в сравнении), либо очищается. Варианты: свернуть запросом с агрегатом МАКСИМУМ(Колонка) или МИНИМУМ(Колонка), либо использовать ручной обход и задать своё правило выбора значения.

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

Для таблицы значений на тонком клиенте метод недоступен — таблица значений вообще не существует в клиентском контексте управляемой формы. Свёртку выполняют в серверной процедуре формы или в модуле объекта, а на клиент возвращают готовый результат.

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

Если документ уже записан в базу, можно обратиться к его табличной части напрямую: ВЫБРАТЬ ... ИЗ Документ.РеализацияТоваровУслуг.Товары ГДЕ Ссылка = &Ссылка СГРУППИРОВАТЬ ПО .... Для ещё не записанного документа доступен только вариант с передачей таблицы значений параметром.

Что делать, если после свёртки сумма НДС не сходится?

Включите ставку НДС в колонки группировки и суммируйте колонку «СуммаНДС» вместе с «Сумма». Если НДС рассчитывается формулой от суммы, пересчитайте его после свёртки по каждой строке с округлением до двух знаков — суммирование уже округлённых значений часто даёт расхождения в копейках.

Итог

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

Основной инструмент — метод Свернуть("колонки группировки", "суммируемые колонки") применительно к выгруженной таблице значений. Включайте в группировку все колонки, определяющие уникальность строки (цена, ставка НДС, склад), иначе данные потеряются или суммы разойдутся. В управляемой форме свёртку выполняйте на сервере. Контрольный признак корректности — итог по сумме до и после свёртки совпадает.