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

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

Приветствуем всех разработчиков и поддерживающих конфигурации на платформе 1С:Предприятие 7.7! Работа с таблицами значений (ТЗ) — это ежедневная практика для любого программиста 1С. Одной из самых популярных операций при подготовке данных для отчетов или проведения документов является группировка строк с суммированием числовых показателей. В этой статье мы подробно разберем, как правильно использовать метод Свернуть, почему при его вызове может возникнуть странное поведение (например, когда числа не суммируются), и какие подводные камни нужно учитывать, чтобы не потерять важные данные.

Постановка задачи и синтаксис метода Свернуть()

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

Давайте подробно изучим синтаксис этого метода:

Свернуть(ГруппКолонки, СуммКолонки)

Параметры метода принимают следующие значения:

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

Рассмотрим простейший пример кода:


ТЗ = СоздатьОбъект("ТаблицаЗначений");
ТЗ.НоваяКолонка("КодСтроки");
ТЗ.НоваяКолонка("Количество");

// Заполняем тестовыми данными
ТЗ.НоваяСтрока();
ТЗ.КодСтроки = "001";
ТЗ.Количество = 1;

ТЗ.НоваяСтрока();
ТЗ.КодСтроки = "001";
ТЗ.Количество = 1;

// Выполняем свертку
ТЗ.Свернуть("КодСтроки", "Количество");

После выполнения этого кода мы ожидаем получить одну строку со значением кода строки "001" и количеством "2". Но что делать, если вместо ожидаемой двойки мы получаем единицу? Давайте разберем эту проблему.

Выясняем причину: почему вместо суммы получается исходное значение?

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

Дело в типизации колонок таблицы значений. В платформе 1С 7.7 метод Свернуть выполняет математическое сложение исключительно для колонок с числовым типом данных. Если при создании таблицы значений тип колонки не был явно определен как числовой, либо если колонка была заполнена строками (например, текстовым значением "1" вместо числа 1), платформа ведет себя следующим образом:

Решение проблемы: правильная типизация колонок

Для того чтобы свертка работала корректно и математически точно, нам необходимо гарантировать числовой тип данных для суммируемых колонок. Рассмотрим два основных сценария решения этой проблемы.

Сценарий 1. Явное задание типа при создании колонок ТЗ

Если таблица значений создается вами программно с нуля, обязательно указывайте тип данных "Число" при создании колонок с помощью метода НоваяКолонка. Разберем по шагам правильное объявление структуры таблицы значений:


ТЗ = СоздатьОбъект("ТаблицаЗначений");
// Текстовая колонка для группировки
ТЗ.НоваяКолонка("КодСтроки", "Строка", 10); 
// Числовые колонки для суммирования (длина 15, точность 2 знака после запятой)
ТЗ.НоваяКолонка("Колонка1", "Число", 15, 2);
ТЗ.НоваяКолонка("Колонка2", "Число", 15, 2);
ТЗ.НоваяКолонка("Колонка3", "Число", 15, 2);

// Наполняем данными и сворачиваем
ТЗ.Свернуть("КодСтроки", "Колонка1, Колонка2, Колонка3");

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

Сценарий 2. Преобразование типов данных в уже заполненной таблице

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

Проанализируем пример кода, реализующий этот алгоритм:


// Предположим, что ТЗ уже заполнена какими-то данными извне
// Пробегаем по всем строкам таблицы значений
ТЗ.ВыбратьСтроки();
Пока ТЗ.ПолучитьСтроку() = 1 Цикл
    // Принудительно преобразуем текстовые единицы в настоящие числа
    ТЗ.Колонка1 = Число(ТЗ.Колонка1);
    ТЗ.Колонка2 = Число(ТЗ.Колонка2);
    ТЗ.Колонка3 = Число(ТЗ.Колонка3);
КонецЦикла;

// Теперь, когда типы приведены к числу, выполняем свертку
ТЗ.Свернуть("КодСтроки", "Колонка1, Колонка2, Колонка3");

Важные технические нюансы и скрытые опасности метода Свернуть()

Помимо проблемы с типами данных, существует еще несколько важных особенностей работы метода Свернуть в 1С 7.7, о которых должен знать каждый разработчик.

1. Безвозвратное удаление неуказанных колонок.
Это один из важнейших нюансов работы платформы. Когда вы вызываете метод Свернуть(ГруппКолонки, СуммКолонки), абсолютно все колонки таблицы значений, которые не были перечислены ни в первом параметре (группировка), ни во втором параметре (суммирование), будут полностью и безвозвратно удалены из структуры вашей таблицы значений вместе со всеми содержащимися в них данными.

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

2. Идентификация колонок по имени, а не по номерам.
Хотя синтаксис 1С 7.7 позволяет передавать в метод номера колонок (например, ТЗ.Свернуть("1", "2, 3")), использовать этот подход крайне не рекомендуется по следующим причинам:

3. Чувствительность к регистру символов.
Имена колонок, передаваемые в качестве параметров метода Свернуть, должны строго соответствовать регистру символов, заданному при их создании в методе НоваяКолонка. Ошибка в регистре (например, написание "кодстроки" вместо оригинального "КодСтроки") может привести к тому, что платформа проигнорирует колонку или вызовет ошибку времени выполнения.

4. Работа со специальными типами данных (Строки и Даты).
Помните, что метод Свернуть не умеет производить конкатенацию (объединение) строк. Вы не сможете сложить строки "Иванов" и "Петров" в одну ячейку "Иванов, Петров". Строковые значения можно использовать только в качестве колонок группировки. Что касается типа "Дата", пустые значения дат платформа считает уникальным значением. Если у вас в группируемой колонке одна дата заполнена, а во второй строке пустая, эти строки никогда не свернутся в одну.

Мы подробно разобрали принципы работы метода Свернуть в 1С 7.7. Будьте внимательны к типам данных ваших колонок, всегда перепроверяйте передаваемые идентификаторы и помните про безвозвратное удаление неуказанных колонок — это убережет вас от трудноловимых ошибок в коде!

← На главную