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