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