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