Как правильно использовать метод Свернуть для таблицы значений в 1С и какие колонки останутся после группировки?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с коллекцией ТаблицаЗначений разработчики часто сталкиваются с необходимостью объединить дублирующиеся строки и просуммировать числовые показатели. Для этого в платформе 1С предусмотрен встроенный метод Свернуть(). Однако его некорректный вызов может привести к непредвиденному удалению данных или аварийному завершению работы алгоритма с ошибкой времени выполнения.

Проанализируем типичную ситуацию: в исходной таблице присутствуют колонки Номенклатура, Характеристика, ВНаличииОстаток, НоменклатураНаименование и ХарактеристикаНаименование. Выясним причину ошибок при вызове метода, разберем состав результирующих колонок и рассмотрим правильные варианты реализации группировки.

Анализ ошибки синтаксиса параметров

Посмотрим на пример ошибочного вызова метода:

ТзХР.Свернуть("Номенклатура", СтрТч.Номенклатура);

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

Если во второй параметр передается объект ссылки, число или имя несуществующего поля, платформа генерирует исключение «Поле не найдено» или «Неверное значение параметров».

Правила работы метода Свернуть

Разберем по шагам ключевые особенности функционирования метода:

  1. Строковые параметры: метод принимает два строковых параметра — КолонкиГруппировок и КолонкиСуммирования. Имена колонок перечисляются через запятую в виде обычной строки.
  2. Удаление неуказанных колонок: после выполнения метода в таблице значений остаются только те колонки, которые были явно переданы в первом или втором параметре. Все остальные колонки (и содержащиеся в них данные) безвозвратно удаляются из структуры таблицы.
  3. Модификация по месту: метод Свернуть() не возвращает новую таблицу, а изменяет исходный объект.
  4. Типы суммируемых колонок: колонки, указанные во втором параметре, обязательно должны содержать числовой тип данных. Попытка суммирования строк, дат или ссылок вызовет ошибку выполнения.

Корректный пример использования метода

Рассмотрим правильный синтаксис вызова метода, когда необходимо сгруппировать данные по номенклатуре и характеристике с суммированием остатка:


// Создаем копию, если исходная таблица с полным набором полей нужна дальше
ТзСвернутая = ТзХР.Скопировать();

// Сворачиваем таблицу по колонкам группировки и суммирования
ТзСвернутая.Свернуть("Номенклатура, Характеристика", "ВНаличииОстаток");

// В результате в таблице ТзСвернутая останутся только 3 колонки:
// Номенклатура, Характеристика, ВНаличииОстаток

Если требуется получить только уникальные комбинации без суммирования числовых полей, второй параметр можно опустить:


ТзУникальныеПозиции = ТзХР.Скопировать();
ТзУникальныеПозиции.Свернуть("Номенклатура, Характеристика");

Альтернативные способы группировки данных

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

Вариант 1. Использование языка запросов и временных таблиц

Передача таблицы значений в запрос позволяет использовать всю мощь агрегатных функций языка 1С:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |    ИсходнаяТЗ.Номенклатура КАК Номенклатура,
    |    ИсходнаяТЗ.Характеристика КАК Характеристика,
    |    МАКСИМУМ(ИсходнаяТЗ.НоменклатураНаименование) КАК НоменклатураНаименование,
    |    МАКСИМУМ(ИсходнаяТЗ.ХарактеристикаНаименование) КАК ХарактеристикаНаименование,
    |    СУММА(ИсходнаяТЗ.ВНаличииОстаток) КАК ВНаличииОстаток
    |ПОМЕСТИТЬ ВТ_Свернутая
    |ИЗ
    |    &ТаблицаИсточника КАК ИсходнаяТЗ
    |СГРУППИРОВАТЬ ПО
    |    ИсходнаяТЗ.Номенклатура,
    |    ИсходнаяТЗ.Характеристика
    |;
    |ВЫБРАТЬ * ИЗ ВТ_Свернутая КАК ВТ_Свернутая";

Запрос.УстановитьПараметр("ТаблицаИсточника", ТзХР);
ТзРезультат = Запрос.Выполнить().Выгрузить();

Вариант 2. Ручная группировка с помощью объекта Соответствие

Для сложных алгоритмов или нестандартных правил агрегации данных можно применить обход строк через объект Соответствие:


ТаблицаИтогов = Новый Соответствие;

Для Каждого СтрТЗ Из ТзХР Цикл
    Ключ = Новый Структура("Номенклатура, Характеристика", СтрТЗ.Номенклатура, СтрТЗ.Характеристика);
    
    ТекущийОстаток = ТаблицаИтогов[Ключ];
    Если ТекущийОстаток = Неопределено Тогда
        ТаблицаИтогов.Вставить(Ключ, СтрТЗ.ВНаличииОстаток);
    Иначе
        ТаблицаИтогов.Вставить(Ключ, ТекущийОстаток + СтрТЗ.ВНаличииОстаток);
    КонецЕсли;
КонецЦикла;

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

← На главную