Как программно объединить ячейки в табличном документе отчета на СКД?

Программист 1С v8.3 (Управляемые формы) Бухгалтерский учет
← На главную

При разработке отчетов на системе компоновки данных (СКД) часто возникает задача визуального улучшения формы. Одной из таких задач является объединение ячеек в колонках, где данные дублируются (например, наименование контрагента или номер договора), чтобы отчет выглядел более аккуратным и читаемым. Стандартные группировки не всегда подходят, так как они меняют структуру отчета, а нам может потребоваться именно визуальное объединение в плоской таблице.

В этой статье мы подробно разберем, как решить эту задачу несколькими способами: от штатных настроек СКД до написания кода в модуле объекта отчета.

Способ 1. Использование встроенной настройки СКД «Объединять одинаковые значения»

Прежде чем переходить к написанию сложного кода, проанализируем стандартные возможности системы компоновки данных. В СКД существует встроенный механизм, который позволяет автоматически объединять одинаковые значения в колонках.

Для этого выполним следующие действия:

  1. Откроем схему компоновки данных и перейдем на вкладку Настройки.
  2. Выберем нужную группировку или уровень «Отчет».
  3. Перейдем на вкладку Выбранные поля.
  4. Нажмем правой кнопкой мыши на поле, которое нужно объединять, и выберем пункт Свойства выбранного поля.
  5. Установим флажок в поле Объединять одинаковые значения.

Этот метод отлично работает для простых линейных отчетов. Однако, если структура отчета сложная или требуется специфическое условие объединения, этот флажок может не дать нужного результата. В таких случаях мы переходим к программным методам.

Способ 2. Программная обработка результата в модуле объекта

Если штатные средства не справляются, мы можем вмешаться в процесс формирования отчета. Для этого используется процедура ПриКомпоновкеРезультата в модуле объекта отчета. Суть метода заключается в том, чтобы остановить стандартный вывод, сформировать отчет программно, а затем «пройтись» по готовому табличному документу и объединить нужные области.

Разберем по шагам реализацию этого метода. Рассмотрим пример кода, который необходимо вставить в модуль объекта:


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

Проанализируем этот код. Мы используем объект ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент, чтобы вручную заполнить ДокументРезультат. После вывода мы запускаем цикл по нужным колонкам. Метод Область() позволяет нам обращаться к конкретным ячейкам по их координатам, а метод Объединить() выполняет визуальное слияние. Для реализации более сложных алгоритмов формирования отчетов можно использовать примеры программной работы со схемой компоновки данных.

Способ 3. Динамический поиск колонок

Рассмотрим ситуацию, когда пользователь может менять состав полей отчета. В этом случае жесткое указание номеров колонок (1, 3, 5) приведет к ошибкам. Выясним, как сделать наш алгоритм более гибким.

Для этого мы можем добавить функцию поиска номера колонки по заголовку. Мы проанализируем шапку табличного документа и найдем нужные индексы динамически:


Функция НайтиНомерКолонкиПоЗаголовку(ТабДок, ИмяЗаголовка)
	Для НомерКол = 1 По ТабДок.ШиринаТаблицы Цикл
		Если Найти(ТабДок.Область(1, НомерКол).Текст, ИмяЗаголовка) > 0 Тогда
			Возврат НомерКол;
		КонецЕсли;
	КонецЦикла;
	Возврат 0;
КонецФункции

Теперь вместо ОбъединяемыеКолонки.Добавить(1) мы будем использовать результат поиска функции. Это защитит код от поломок при изменении настроек пользователем.

Способ 4. Визуальная имитация объединения через условное оформление

Посмотрим на альтернативный вариант. Иногда реальное объединение ячеек нежелательно, так как оно мешает пользователю сортировать данные в сформированном отчете или некорректно выгружается в Excel. В этом случае мы можем применить Условное оформление.

Разберем логику:

  1. В настройках СКД добавим правило условного оформления.
  2. В оформлении выберем Цвет текста, равный цвету фона (обычно белый), и отключим границы (верхнюю или нижнюю).
  3. В условии укажем проверку на равенство текущего значения предыдущему (это потребует добавления технического поля в набор данных).

Хотя этот метод сложнее в настройке логики «предыдущего значения», он сохраняет структуру ячеек нетронутой, что важно для дальнейшей аналитической работы с отчетом.

Важные замечания для типовых конфигураций

Проанализируем контекст использования кода. Если вы работаете в конфигурации, использующей БСП (например, Бухгалтерия для Казахстана 3.0), помните, что установка СтандартнаяОбработка = Ложь может отключить некоторые сервисные возможности (расшифровка, автоматическое сохранение настроек).

Чтобы избежать проблем, старайтесь:

Таким образом, мы рассмотрели различные подходы к оформлению табличного документа. Выбор метода зависит от сложности вашего отчета и требований к его функциональности после формирования. В качестве альтернативного решения для компактного вывода информации в отчете можно применить способ сбора значений колонки из нескольких строк в СКД.

← На главную