При формировании сложных отчетов программным путем (без использования Системы компоновки данных — СКД) разработчики часто сталкиваются с необходимостью группировки колонок. Платформа 1С предлагает для этого удобный встроенный инструмент — автогруппировку. Однако при его использовании легко допустить ошибку, из-за которой структура колонок просто не отобразится или будет работать некорректно. В этой статье мы подробно разберем, как устроен механизм автогруппировки «под капотом», почему он может ломаться и как настроить сворачивание колонок в нужную вам сторону.
Рассмотрим типичную ситуацию. Разработчик пытается создать отчет с горизонтальной группировкой, используя следующий код:
ТабДок = Новый ТабличныйДокумент;
Секция = ТабДок.ПолучитьОбласть("R1C1");
ТабДок.НачатьАвтогруппировкуКолонок();
Секция.Область().Текст = "Параметр";
ТабДок.Вывести(Секция, 1, "1");
Секция.Область().Текст = 1;
ТабДок.Присоединить(Секция, 2, "2");
Секция.Область().Текст = 1;
ТабДок.Присоединить(Секция, 2, "2");
Секция.Область().Текст = 1;
ТабДок.Присоединить(Секция, 2, "2");
ТабДок.ЗакончитьАвтогруппировкуКолонок();
ТабДок.Показать("Пример использования гор. автогруппировки");
На первый взгляд код выглядит логично: мы открываем автогруппировку методом НачатьАвтогруппировкуКолонок(), выводим первую колонку с уровнем 1, затем присоединяем три колонки с уровнем 2 и закрываем автогруппировку методом ЗакончитьАвтогруппировкуКолонок(). Однако при формировании такого документа структура (плюсики для сворачивания колонок) не появляется.
Причина кроется в правилах определения границ групп платформой 1С. Механизм автогруппировки анализирует последовательность выводимых колонок и их уровни. Группа колонок текущего уровня (например, уровня 2) считается незавершенной, пока платформа не встретит колонку более высокого уровня (численно меньшего, например, уровня 1). Если мы просто вывели три колонки уровня 2 и сразу вызвали ЗакончитьАвтогруппировкуКолонок(), платформа не понимает, где должна заканчиваться группа, и автогруппировка сбрасывается.
Чтобы автогруппировка сработала корректно, мы должны явно «закрыть» группу колонок уровня 2. Для этого необходимо вывести (присоединить) колонку уровня 1 после детальных колонок. Эта закрывающая колонка обычно играет роль итоговой колонки для данной группы.
Проанализируем исправленный алгоритм работы:
НачатьАвтогруппировкуКолонок().ЗакончитьАвтогруппировкуКолонок().Давайте посмотрим на скорректированный пример кода:
ТабДок = Новый ТабличныйДокумент;
Секция = ТабДок.ПолучитьОбласть("R1C1");
ТабДок.НачатьАвтогруппировкуКолонок();
// Выводим заголовок строки или первую колонку уровня 1
Секция.Область().Текст = "Параметр";
ТабДок.Вывести(Секция, 1, "Группа 1");
// Присоединяем детальные колонки уровня 2
Секция.Область().Текст = "Данные 1";
ТабДок.Присоединить(Секция, 2, "Группа 2");
Секция.Область().Текст = "Данные 2";
ТабДок.Присоединить(Секция, 2, "Группа 2");
Секция.Область().Текст = "Данные 3";
ТабДок.Присоединить(Секция, 2, "Группа 2");
// Закрываем группу уровня 2, присоединяя колонку уровня 1 (Итог)
Секция.Область().Текст = "Итого";
ТабДок.Присоединить(Секция, 1, "Группа 1");
ТабДок.ЗакончитьАвтогруппировкуКолонок();
ТабДок.Показать("Правильная автогруппировка");
После такого изменения платформа успешно определит границы группы колонок уровня 2, и в шапке табличного документа появятся элементы управления группировкой.
По умолчанию при сворачивании группы колонок видимой остается крайняя левая колонка, а маркеры сворачивания («+» / «-») располагаются слева. Однако в классических отчетах итоговая колонка чаще всего располагается справа от детальных данных, и при сворачивании должна оставаться видимой именно она.
Для настройки этого поведения в ТабличныйДокумент предусмотрены специальные свойства:
ИтогиСправа — отвечает за горизонтальную группировку (колонки). Если установить ТабДок.ИтогиСправа = Истина, то маркеры сворачивания переместятся на правую сторону группы колонок. При сворачивании детальные колонки скроются влево, оставив видимой только итоговую колонку, расположенную справа.ИтогиСнизу — аналогичное свойство для вертикальной группировки (строк). Если установить ТабДок.ИтогиСнизу = Истина, маркеры сворачивания будут отображаться внизу группы (под детальными строками), что удобно, если строка итогов по группе выводится под детальными записями. Если установить значение Ложь, маркеры будут находиться сверху (над детальными строками).Рассмотрим пример настройки этих свойств перед выводом данных:
ТабДок = Новый ТабличныйДокумент;
// Настраиваем отображение итогов справа для колонок
ТабДок.ИтогиСправа = Истина;
// Настраиваем отображение итогов снизу для строк
ТабДок.ИтогиСнизу = Истина;
Помимо интерактивного сворачивания мышкой, разработчик может полностью управлять поведением и отображением созданной структуры из кода 1С. Рассмотрим наиболее полезные методы и свойства:
1. Начальное состояние выводимой группы. Четвертый параметр методов Вывести() и Присоединить() называется <Открыта> и принимает булево значение. Если вам необходимо, чтобы отчет при формировании сразу выводился со свернутыми колонками определенной группы, передайте в этот параметр значение Ложь:
// Выводим колонку с закрытой по умолчанию группой
ТабДок.Присоединить(Секция, 2, "ГруппаКолонок", Ложь);
2. Программное сворачивание до определенного уровня. С помощью методов ПоказатьУровеньГруппировокКолонок() и ПоказатьУровеньГруппировокСтрок() можно в один вызов свернуть или развернуть весь документ до нужной глубины вложенности. Индексация уровней в этих методах начинается с 0 (где 0 — полностью свернутый документ).
Если мы хотим программно полностью свернуть все колонки в сформированном документе, мы можем динамически определить количество уровней и свернуть их в цикле:
КоличествоУровней = ТабДок.КоличествоУровнейГруппировокКолонок() - 1;
Для Уровень = 1 По КоличествоУровней Цикл
ТабДок.ПоказатьУровеньГруппировокКолонок(КоличествоУровней - Уровень);
КонецЦикла;
3. Скрытие интерфейса группировок. Иногда требуется сформировать структуру документа (например, для программного анализа или для возможности быстрого сворачивания через API), но при этом скрыть от пользователя сами кнопки «+» и «-» и серые линии группировок на панели. Для этого используется свойство ОтображатьГруппировки:
// Скрываем элементы управления группировкой с экрана пользователя
ТабДок.ОтображатьГруппировки = Ложь;
При выводе иерархических данных по строкам (вертикальная группировка) разработчикам часто приходится вручную добавлять пробелы перед текстом зависимых элементов, чтобы визуально показать подчиненность. В 1С этот процесс можно автоматизировать с помощью свойства ячейки АвтоОтступ.
Если в макете для ячейки установить свойство АвтоОтступ в значение, отличное от нуля (например, 5), платформа будет автоматически добавлять отступы слева при выводе строк с разным уровнем группировки. Чем больше числовое значение уровня строки в методе Вывести(), тем больше будет визуальный отступ текста в этой ячейке. Это значительно упрощает код и делает отчеты более аккуратными.
Объединим все изученные методики в один качественный пример. Создадим таблицу, в которой будут сгруппированы продажи по месяцам внутри квартала, а итоговая колонка квартала будет находиться справа и служить закрывающим элементом для корректной работы автогруппировки.
ТабДок = Новый ТабличныйДокумент;
ТабДок.ИтогиСправа = Истина; // Маркеры сворачивания будут справа
СекцияШапка = ТабДок.ПолучитьОбласть("R1C1");
// Включаем автогруппировку колонок
ТабДок.НачатьАвтогруппировкуКолонок();
// Строим шапку: Название аналитики (Уровень 1)
СекцияШапка.Область().Текст = "Номенклатура";
ТабДок.Вывести(СекцияШапка, 1, "Аналитика");
// Выводим 1-й квартал: детальные месяцы (Уровень 2)
СекцияШапка.Область().Текст = "Январь";
ТабДок.Присоединить(СекцияШапка, 2, "1 Квартал");
СекцияШапка.Область().Текст = "Февраль";
ТабДок.Присоединить(СекцияШапка, 2, "1 Квартал");
СекцияШапка.Область().Текст = "Март";
ТабДок.Присоединить(СекцияШапка, 2, "1 Квартал");
// Закрываем группу 1-го квартала итоговой колонкой (Уровень 1)
СекцияШапка.Область().Текст = "Итого 1 Квартал";
ТабДок.Присоединить(СекцияШапка, 1, "Аналитика");
// Выводим 2-й квартал: детальные месяцы (Уровень 2)
СекцияШапка.Область().Текст = "Апрель";
ТабДок.Присоединить(СекцияШапка, 2, "2 Квартал");
СекцияШапка.Область().Текст = "Май";
ТабДок.Присоединить(СекцияШапка, 2, "2 Квартал");
СекцияШапка.Область().Текст = "Июнь";
ТабДок.Присоединить(СекцияШапка, 2, "2 Квартал");
// Закрываем группу 2-го квартала итоговой колонкой (Уровень 1)
СекцияШапка.Область().Текст = "Итого 2 Квартал";
ТабДок.Присоединить(СекцияШапка, 1, "Аналитика");
// Завершаем процесс группировки колонок
ТабДок.ЗакончитьАвтогруппировкуКолонок();
// Выводим результат на экран
ТабДок.Показать("Отчет по продажам с группировкой");
Благодаря такому подходу структура колонок построится безупречно. Пользователь сможет сворачивать и разворачивать кварталы кнопками интерфейса, при этом итоговые колонки всегда будут оставаться на виду справа от свернутых данных.