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