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