Как реализовать иерархию и группировки в табличном документе 1С программно

Программист 1С v8.3 (Управляемые формы) Бухгалтерский учет
← На главную

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

Способ 1: Использование уровней в методе Вывести

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

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


Выборка = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);

Пока Выборка.Следующий() Цикл
    // Получаем область строки из макета
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, Выборка);
    
    // Выводим область, указывая текущий уровень выборки
    // Уровень() возвращает числовое значение вложенности (0, 1, 2...)
    ТабДок.Вывести(ОбластьСтрока, Выборка.Уровень());
КонецЦикла;

Важный нюанс: Чтобы группировки отобразились в левой части документа, необходимо перед началом вывода установить свойство Автогруппировка в значение Истина. Это заставит систему автоматически связывать строки разных уровней в иерархическое дерево.

Способ 2: Ручное управление группами строк

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

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


Процедура ВывестиДеревоРекурсивно(СтрокиДерева, Макет, ТабДок)
    
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    ОбластьГруппа = Макет.ПолучитьОбласть("СтрокаГруппа");
    
    Для Каждого ТекущаяСтрока Из СтрокиДерева Цикл
        
        Если ТекущаяСтрока.Строки.Количество() > 0 Тогда
            // Если у строки есть подчиненные элементы, выводим её как заголовок группы
            ОбластьГруппа.Параметры.Заполнить(ТекущаяСтрока);
            ТабДок.Вывести(ОбластьГруппа, ТекущаяСтрока.Уровень());
            
            // Открываем новую группу строк. 
            // Второй параметр "Ложь" означает, что группа будет изначально развернута.
            ТабДок.НачатьГруппуСтрок(ТекущаяСтрока.Наименование, Ложь);
            
            // Рекурсивно вызываем эту же процедуру для подчиненных строк
            ВывестиДеревоРекурсивно(ТекущаяСтрока.Строки, Макет, ТабДок);
            
            // Обязательно закрываем группу после вывода всех вложенных строк
            ТабДок.ЗакончитьГруппуСтрок();
        Иначе
            // Обычная детальная запись
            ОбластьСтрока.Параметры.Заполнить(ТекущаяСтрока);
            ТабДок.Вывести(ОбластьСтрока, ТекущаяСтрока.Уровень());
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры

Способ 3: Визуальный отступ без системных группировок

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

Проанализируем пример настройки отступа программно:


Пока Выборка.Следующий() Цикл
    Область = Макет.ПолучитьОбласть("Строка");
    
    // Определяем ячейку, в которой должен быть отступ (например, "Наименование")
    ЯчейкаНаименование = Область.Область("R1C1"); // Адрес ячейки внутри области
    
    // Устанавливаем отступ в зависимости от уровня записи в запросе
    ЯчейкаНаименование.Отступ = Выборка.Уровень() * 2;
    
    Область.Параметры.Заполнить(Выборка);
    ТабДок.Вывести(Область);
КонецЦикла;

Оформление уровней и итоги

Для создания профессионального отчета важно выделять родительские уровни визуально. Мы можем программно менять шрифт или фон области в зависимости от типа записи.

  1. Выделение жирным шрифтом: Если запись является итоговой (группировкой), установим свойство Шрифт.
  2. Цветовое кодирование: Можно задать разный цвет фона для разных уровней вложенности (например, темно-серый для корня, светло-серый для подуровней).
  3. Управление видимостью: Используйте метод ТабДок.ПоказатьУровеньГруппировокСтрок(НомерУровня), чтобы при открытии отчета все детальные записи были скрыты, а видны только основные разделы.

Посмотрим, как это реализовать в цикле вывода:


Пока Выборка.Следующий() Цикл
    Область = Макет.ПолучитьОбласть("Строка");
    
    Если Выборка.ТипЗаписи() = ТипЗаписиЗапроса.ИтогПоИерархии Тогда
        // Делаем шрифт жирным для родительских узлов
        Область.ТекущаяОбласть.Шрифт = Новый Шрифт(Область.ТекущаяОбласть.Шрифт, , , Истина);
        // Можно также добавить фоновый цвет
        Область.ТекущаяОбласть.ЦветФона = ЦветаСтиля.ЦветФонаГруппировки;
    КонецЕсли;
    
    Область.Параметры.Заполнить(Выборка);
    ТабДок.Вывести(Область, Выборка.Уровень());
КонецЦикла;

Типичные ошибки при работе с иерархией

Разберем основные моменты, на которых часто спотыкаются разработчики:

1. Отсутствие настройки отображения группировок. Если вы используете Вывести(Область, Уровень), но не видите кнопок управления слева, проверьте свойство ТабДок.ОтображатьГруппировки = Истина;.

2. Смешивание уровней. При обходе иерархического запроса важно помнить, что уровень 0 — это самые верхние итоги (Общие итоги), уровень 1 — первый уровень группировки и так далее. Если вы начнете вывод сразу со 2-го уровня, структура группировок может отобразиться некорректно.

3. Использование ИТОГИ ПО ... ИЕРАРХИЯ. Помните, что ключевое слово ИЕРАРХИЯ в запросе добавляет в выборку всех родителей объекта (например, все вышестоящие группы справочника Номенклатура), даже если по ним нет движений в базе. Это нужно учитывать при расчете остатков и оборотов.

В завершение отметим, что ручной вывод иерархии дает полный контроль над внешним видом документа, позволяя создавать сложные печатные формы, которые невозможно или крайне трудно реализовать стандартными средствами СКД.

← На главную