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