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