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