При разработке отчетов в 1С 7.7 нередко возникает необходимость динамически формировать колонки в зависимости от выбранного пользователем периода (например, разбивка по месяцам, декадам или дням). Сложность возникает, когда полученную ТаблицаЗначений требуется сгруппировать по строкам (например, по контрагенту) с помощью метода Свернуть(), просуммировав данные по всем созданным динамическим колонкам.
Рассмотрим, почему при стандартном вызове метода Свернуть() колонки могут исчезать, и разберем несколько способов решения этой задачи.
Проанализируем особенности работы метода ТаблицаЗначений.Свернуть() в платформе 1С 7.7:
Таб.Свернуть("ГруппировочныеКолонки", "СуммируемыеКолонки").ТабЗнач.НоваяКолонка(,"Число")), платформа присваивает им автоматические системные имена вида _1, _2 и т.д., однако обращаться к ним «вслепую» без предварительного формирования списка нельзя. Если передать в метод только группировочную колонку (ТабЗнач.Свернуть("Контрагент", "")), на выходе останется таблица ровно из одной этой колонки.Разберем наиболее надежный и прозрачный способ: при создании динамических колонок мы сразу задаем им понятные идентификаторы и параллельно формируем строку со списком колонок для последующей свертки.
Посмотрим на пример реализации с циклом по периодам:
// Создаем базовые колонки
ТабЗнач1.НоваяКолонка("Контрагент", "Справочник.Контрагенты");
НачДаты = НачДата;
СтрокаСвертки = "";
к = 0;
Пока НачДаты <= КонДата Цикл
к = к + 1;
ИмяКолонки = "Кол_" + к;
// Формируем список суммируемых колонок через запятую
Если ПустаяСтрока(СтрокаСвертки) = 1 Тогда
СтрокаСвертки = ИмяКолонки;
Иначе
СтрокаСвертки = СтрокаСвертки + "," + ИмяКолонки;
КонецЕсли;
// Создаем числовую колонку с заданным именем, длиной и точностью
ТабЗнач1.НоваяКолонка(ИмяКолонки, "Число", 15, 2, Формат(НачДаты, "ДФ=ММММ гггг"));
НачДаты = ДобавитьМесяц(НачДаты, 1);
КонецЦикла;
// Заполнение таблицы данными (пропущено для краткости)
// ...
// Выполняем свертку по контрагенту и всем созданным колонкам
ТабЗнач1.Свернуть("Контрагент", СтрокаСвертки);
Также можно формировать осмысленные имена колонок на базе даты. Важно помнить: идентификатор колонки в 1С 7.7 подчиняется правилам именования переменных и не должен содержать точек или спецсимволов. Поэтому дату необходимо предварительно форматировать:
ИмяКолонки = "Период_" + СтрЗаменить(Формат(НачДаты, "ДДДММГГГГ"), ".", "_");
Метод Свернуть() в 1С 7.7 поддерживает передачу порядковых номеров колонок вместо их строковых идентификаторов (нумерация начинается с 1).
Если колонки уже созданы в таблице, и вы не формировали строку суммирования на этапе их добавления, можно динамически собрать имена всех колонок перед сверткой с помощью метода ПолучитьПараметрыКолонки():
СтрокаСвертки = "";
ВсегоКолонок = ТабЗнач1.КоличествоКолонок();
// Предполагаем, что 1-я колонка - "Контрагент", а со 2-й начинаются суммы
Для НомКол = 2 По ВсегоКолонок Цикл
ИмяКол = "";
ТабЗнач1.ПолучитьПараметрыКолонки(НомКол,,,, ИмяКол);
// Если имя было пустым, можно использовать системный идентификатор или номер
Если ПустаяСтрока(ИмяКол) = 1 Тогда
ИмяКол = Строка(НомКол);
КонецЕсли;
СтрокаСвертки = СтрокаСвертки + ?(ПустаяСтрока(СтрокаСвертки) = 1, "", ",") + ИмяКол;
КонецЦикла;
ТабЗнач1.Свернуть("Контрагент", СтрокаСвертки);
Построение двумерных матриц с динамическим набором колонок в оперативной памяти 1С 7.7 — ресурсоемкая операция. При больших объемах данных такая таблица потребляет много памяти, а свертка широкой таблицы работает заметно медленнее.
Проанализируем альтернативный подход — хранение данных в плоском виде с фиксированной структурой:
Контрагент, Период, Сумма.
ТабЗнач.Свернуть("Контрагент,Период", "Сумма");
Таб.ВывестиСекцию() для строк и Таб.ПрисоединитьСекцию() для колонок-периодов).Также для подобных задач в 1С 7.7 эффективно использовать встроенный объект Запрос с конструкцией Периодичность Месяц; и группировками Группировка Контрагент; и Группировка Месяц;, что избавляет от необходимости вручную управлять динамическими колонками в коде.