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