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