Как свернуть ТаблицуЗначений с динамическим количеством колонок в 1С 7.7?

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

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

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

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

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

  1. Метод принимает два строковых параметра: список группировочных колонок и список суммируемых колонок через запятую: Таб.Свернуть("ГруппировочныеКолонки", "СуммируемыеКолонки").
  2. Все колонки, не указанные ни в первом, ни во втором параметре, безвозвратно удаляются из таблицы.
  3. Если колонки создаются динамически без указания идентификатора (например, ТабЗнач.НоваяКолонка(,"Число")), платформа присваивает им автоматические системные имена вида _1, _2 и т.д., однако обращаться к ним «вслепую» без предварительного формирования списка нельзя. Если передать в метод только группировочную колонку (ТабЗнач.Свернуть("Контрагент", "")), на выходе останется таблица ровно из одной этой колонки.
  4. Суммируемые колонки должны иметь строго числовой тип. Если в суммируемую ячейку попадет строка или незаполненное значение нечислового типа, платформа выдаст ошибку или результат подсчета будет неверным.

Способ 1. Явное именование колонок и динамическое формирование строки суммирования

Разберем наиболее надежный и прозрачный способ: при создании динамических колонок мы сразу задаем им понятные идентификаторы и параллельно формируем строку со списком колонок для последующей свертки.

Посмотрим на пример реализации с циклом по периодам:


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

НачДаты = НачДата;
СтрокаСвертки = "";
к = 0;

Пока НачДаты <= КонДата Цикл
    к = к + 1;
    ИмяКолонки = "Кол_" + к;
    
    // Формируем список суммируемых колонок через запятую
    Если ПустаяСтрока(СтрокаСвертки) = 1 Тогда
        СтрокаСвертки = ИмяКолонки;
    Иначе
        СтрокаСвертки = СтрокаСвертки + "," + ИмяКолонки;
    КонецЕсли;
    
    // Создаем числовую колонку с заданным именем, длиной и точностью
    ТабЗнач1.НоваяКолонка(ИмяКолонки, "Число", 15, 2, Формат(НачДаты, "ДФ=ММММ гггг"));
    
    НачДаты = ДобавитьМесяц(НачДаты, 1);
КонецЦикла;

// Заполнение таблицы данными (пропущено для краткости)
// ...

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

Также можно формировать осмысленные имена колонок на базе даты. Важно помнить: идентификатор колонки в 1С 7.7 подчиняется правилам именования переменных и не должен содержать точек или спецсимволов. Поэтому дату необходимо предварительно форматировать:

ИмяКолонки = "Период_" + СтрЗаменить(Формат(НачДаты, "ДДДММГГГГ"), ".", "_");

Способ 2. Использование номеров колонок или обход метаданных колонок таблицы

Метод Свернуть() в 1С 7.7 поддерживает передачу порядковых номеров колонок вместо их строковых идентификаторов (нумерация начинается с 1).

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


СтрокаСвертки = "";
ВсегоКолонок = ТабЗнач1.КоличествоКолонок();

// Предполагаем, что 1-я колонка - "Контрагент", а со 2-й начинаются суммы
Для НомКол = 2 По ВсегоКолонок Цикл
    ИмяКол = "";
    ТабЗнач1.ПолучитьПараметрыКолонки(НомКол,,,, ИмяКол);
    
    // Если имя было пустым, можно использовать системный идентификатор или номер
    Если ПустаяСтрока(ИмяКол) = 1 Тогда
        ИмяКол = Строка(НомКол);
    КонецЕсли;
    
    СтрокаСвертки = СтрокаСвертки + ?(ПустаяСтрока(СтрокаСвертки) = 1, "", ",") + ИмяКол;
КонецЦикла;

ТабЗнач1.Свернуть("Контрагент", СтрокаСвертки);

Способ 3. Переход на линейную («узкую») структуру таблицы

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

Проанализируем альтернативный подход — хранение данных в плоском виде с фиксированной структурой:

  1. Таблица значений создается с фиксированными колонками: Контрагент, Период, Сумма.
  2. Свертка выполняется элементарно в одну строчку: ТабЗнач.Свернуть("Контрагент,Период", "Сумма");
  3. Трансформация данных в двумерный отчет для пользователя («шапка по месяцам») выполняется не в памяти таблицы значений, а непосредственно при выводе в печатную форму с помощью секций таблицы (Таб.ВывестиСекцию() для строк и Таб.ПрисоединитьСекцию() для колонок-периодов).

Также для подобных задач в 1С 7.7 эффективно использовать встроенный объект Запрос с конструкцией Периодичность Месяц; и группировками Группировка Контрагент; и Группировка Месяц;, что избавляет от необходимости вручную управлять динамическими колонками в коде.

← На главную