СКД. Как объединить заголовки родительских группировок колонок в таблице

Опубликовал Defor в раздел Программирование - Практика программирования

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

Имеем отчет вида:


 

Необходимо одинаковые заголовки группировок объединить.

Предлагаю данную операцию произвести над сформированным табличным документом, используя следующий код:

// Проверка двух смежных ячеек на идентичночность
Функция ОбъединятьЯчейки(ТабДок, индСтр, индКол)

Ячейка = ТабДок.Область(индСтр, индКол);
ЯчейкаСлед = ТабДок.Область(индСтр, индКол+1);
Если
ПустаяСтрока(Ячейка.Текст) Тогда

Возврат ложь

ИначеЕсли
//Проверяем на соответствие заголовка
Ячейка.Текст = ЯчейкаСлед.Текст
// Проверяем на соответствие имени (отсеиваем уже объединенные ячейки)
и Ячейка.Имя = "R"+индСтр+"C"+индКол Тогда

Возврат Истина;

Иначе

Возврат ложь

КонецЕсли;

КонецФункции

// Обработка заголовков таблицы
//
// Параметры
// Табл - < Тип.ТабличныйДокумент> - Табличный документ формы
Процедура ОбработатьЗаголовки(ТабДок)

ОбъединяемаяОбласть = Неопределено;

//Для оптимизации здесь нужно будет ограничить высоту таблицы
Для индСтр=1 По ТабДок.ВысотаТаблицы Цикл

НачальнаяКолонка = 0;
Для
индКол=1 По ТабДок.ШиринаТаблицы Цикл

// определяем начало объединения
Если ОбъединятьЯчейки(ТабДок, индСтр, индКол) Тогда

Если не
НачальнаяКолонка Тогда

НачальнаяКолонка = индКол;

КонецЕсли;

ИначеЕсли
НачальнаяКолонка Тогда
// завершаем объединение

ТекстЗаголовка = ТабДок.Область(индСтр, индКол).Текст;
ОбъединяемаяОбласть = ТабДок.Область(индСтр, НачальнаяКолонка, индСтр, индКол);
ОбъединяемаяОбласть.Объединить();
ОбъединяемаяОбласть.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр;
ОбъединяемаяОбласть.Текст = ТекстЗаголовка;
НачальнаяКолонка = 0;

Иначе

НачальнаяКолонка = 0;

КонецЕсли;

КонецЦикла;

// Если нашли в строке области для объединения то прекращаем дальнейшие поиски
Если не ОбъединяемаяОбласть = Неопределено Тогда

возврат;

КонецЕсли;

КонецЦикла;

КонецПроцедуры

Вставляем вызов после формирования табличного документа:

Результат представлен ниже:

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

 

Благодарности:

На поиски решения вдохновила статья also http://1cskd.ru/2010/07/kak-v-skd-nakryt-kolonki-shapkoj/

p.s.

Добавлен доработанный файл для 8.2, где предоставлен модифицированный пример для нескольких ресурсов (показателей) - спасибо Evgeniy.

Скачать файлы

Наименование Файл Версия Размер
Объединяемые заголовки
.erf 9,99Kb
28.06.13
129
.erf 9,99Kb 129 Скачать
Объединяемые заголовки для 8.2
.erf 10,28Kb
28.06.13
81
.erf 10,28Kb 81 Скачать

См. также

Комментарии
1. Валерий Гуров (Saint) 14 12.11.10 03:09 Сейчас в теме
Если операция производится над сформированным табличным документом, то причём здесь СКД?
2. Defor 79 12.11.10 04:45 Сейчас в теме
Проблема в СКД. При формировании в колонках таблицы вложенных группировок, родительский заголовок группировки, не объединяет заголовки дочерних группировок.


Это решение призвано привести в порядок вертикальные группировки в СКД. Если этот вариант можно использовать еще где нибудь я не против.
3. Дмитрий Малина (malina-da) 10.10.11 10:24 Сейчас в теме
Спасибо за решение, сделал и для горизонтальных и вертикальных ячеек.
4. Игорь (doronin70) 19.01.12 17:58 Сейчас в теме
Классно работает и для вертикальных и для горизонтальных ячеек. А у кого получилось одновременное объединение горизонтальных и верткальных? Например объединенная ячейка должна быть высотой 2 строки и шириной 3 колонки ?
5. Серж Иванов (adminfo2002) 96 20.11.12 15:21 Сейчас в теме
В платформе 8.2 уже все объединяет, если грамотно настроить
6. Сергей Начина (serg_gres) 127 28.11.12 14:25 Сейчас в теме
(5) adminfo2002, серьезно?
Пример в студию.
7. Сергей Начина (serg_gres) 127 28.11.12 14:32 Сейчас в теме
Вопрос автору: объединятся ли смежные ячейки ресурсов с одинаковым значением?
8. Серж Иванов (adminfo2002) 96 28.11.12 16:18 Сейчас в теме
(6) serg_gres, ок, сейчас потрачу полчасика на пример... подожди, не уходи :)
9. Сергей Начина (serg_gres) 127 28.11.12 16:56 Сейчас в теме
10. Defor 79 29.11.12 05:45 Сейчас в теме
(7) serg_gres, не понял, зачем объединять ячейки ресурсов? Если речь идет об общей родительской группировке этих ресурсов, то да объединятся.
11. Defor 79 29.11.12 05:48 Сейчас в теме
(5) adminfo2002, действительно, было бы очень интересно посмотреть на новое решение ...
12. Lubov Lubov (bus1ka) 10.01.13 22:05 Сейчас в теме
Единственное найденное решение, на мой взгляд. И в 8.2 ничего подобного, как ни настраивай...
13. Lubov Lubov (bus1ka) 10.01.13 22:07 Сейчас в теме
(8) adminfo2002, и я жду... )) передо мной сейчас такая же задача. Но как не пыталась, простой настройкой не обошлась
14. Денис Саяпин (sdv88) 78 01.03.13 14:50 Сейчас в теме
мне наоборот надо чтобы родительская группировка не объединялась.. версия платформы 8.2.14.540. есть какая то настройка?
15. Defor 79 07.03.13 08:10 Сейчас в теме
А можно поподробнее описать, в каком виде вы хотите видеть родительские группировки?
16. Денис Саяпин (sdv88) 78 07.03.13 14:30 Сейчас в теме
как в публикации на картинке где без объединения(покупатели или поставщики). чтобы над каждой колонкой было название верхней группировки. то есть начальный вариант в этой публикации
17. Defor 79 18.03.13 09:11 Сейчас в теме
Смотрите скриншот "Настройки СКД"
18. Алекс Ю (AlexO) 114 19.03.13 23:53 Сейчас в теме
(8) adminfo2002,
ок, сейчас потрачу полчасика на пример

Полгода прошло... у вас там временная аномалия? :)
(16) sdv88,
как в публикации на картинке где без объединения

"А вот тут немного снять.. здесь подчистить... тут отрезать...и вот изящная ложка готова!"
"Не, мне баклушу как сделать?!..."
Кто ж поймет этих 1сников...
19. Алекс Ю (AlexO) 114 19.03.13 23:54 Сейчас в теме
(1) Saint,
над сформированным табличным документом, то причём здесь СКД?

Вы знаете способ обработать СКД напрямую?
20. Валерий Гуров (Saint) 14 20.03.13 02:45 Сейчас в теме
(19) AlexO, C добрым утром! Вопрос по комментарию трёхгодичной давности? Тем не менее попытаюсь ещё раз сформулировать: какое отношение описанный алгоритм имеет к СКД? Здесь обрабатывается уже сформированный табличный документ. А как он был сформирован для описанного алгоритма дело десятое. Точно также можно обрабатывать табличный документ, сформированный вручную.
21. Defor 79 20.03.13 05:49 Сейчас в теме
Если данное решение можно применить где-то еще я буду только рад. Но в первую очередь это будет полезно пользователям СКД.
22. Алекс Ю (AlexO) 114 20.03.13 11:13 Сейчас в теме
(20) Saint,
А как он был сформирован для описанного алгоритма дело десятое

Как раз наипервейшее. Потому как СКД настолько закрытый и запутанный механизм, что любое осмысленное вмешательство в него, дающее уверенный результат - уже огромный плюс.
23. marate (kurmanov) 24.06.13 13:44 Сейчас в теме
Спасибо! Полезная вещь, очень помогла.
24. Evgeniy (Evgeniy) 81 27.06.13 14:04 Сейчас в теме
работает только при выводе одного показателя в отчете.
Если делаешь вывод более одного показателя, то объединение не срабатывает:(
25. Defor 79 30.06.13 10:17 Сейчас в теме
Спасибо за замечание, добавлен доработанный пример для 8.2.
26. Родион (lamdth) 10 02.07.13 15:43 Сейчас в теме
Подскажите, если у меня нет кнопки сформировать, и форма рисуется стандартно, как мне использовать данную процедуру?
27. Владимир Клименко (KliMich) 03.07.13 09:56 Сейчас в теме
Спасибо!
Возьму на вооружение.
28. Defor 79 11.07.13 07:02 Сейчас в теме
(26) lamdth,
На форме создайте кнопку, прицепите к ней свой обработчик, текст можно подсмотреть где угодно. Например выдрать из моего отчета этой темы. Пример есть в книге "Руководство разработчика" гл 10.4.
29. Maxim Kolkin (the1) 277 09.10.13 15:13 Сейчас в теме
Нечто подобное методами СКД. Не так красиво, правда http://www.forum.mista.ru/topic.php?id=637203
30. rborovikov (rborovikov) 10.02.14 22:26 Сейчас в теме
А как сделали рисунок "Имеем отчет вида"???
31. Defor 79 18.02.14 16:57 Сейчас в теме
(30) rborovikov,
На скриншоте "Настройки СКД" показан пример настроек или можно скачать приложенный отчет и там посмотреть.
32. Andrey Rudzko (andreich_ru) 07.07.14 12:34 Сейчас в теме
Спасибо, помогло.
Я при использовании немного дополнил функцию ОбъединятьЯчейки():
Функция ОбъединятьЯчейки(ТабДок, индСтр, индКол)

	ТекстДляОбъединения = Новый Массив;
	ТекстДляОбъединения.Добавить("Начальный остаток");
	ТекстДляОбъединения.Добавить("Приход");
	ТекстДляОбъединения.Добавить("Расход");
	ТекстДляОбъединения.Добавить("Конечный остаток");
	
	Ячейка = ТабДок.Область(индСтр, индКол);
	ЯчейкаСлед = ТабДок.Область(индСтр, индКол+1);
	
	Если ПустаяСтрока(Ячейка.Текст) Тогда

		Возврат Ложь

	//Проверяем, чтобы текст был одним из указанных в ТекстДляОбъединения
	ИначеЕсли ТекстДляОбъединения.Найти(Ячейка.Текст) <> Неопределено И Ячейка.Текст = ЯчейкаСлед.Текст И Ячейка.Имя = "R"+индСтр+"C"+индКол Тогда 
		
		Возврат Истина;

	Иначе

		Возврат Ложь

	КонецЕсли;

КонецФункции
...Показать Скрыть

Добавил массив, в котором указал конкретные строки, которые должны быть в ячейках для объединения. Потому что исходный вариант иногда объединял не то, что нужно.
33. Igor Gorbachev (Leits) 1 23.10.14 11:05 Сейчас в теме
скачал для 8.2, процедуры в модуле форме вообще не прорабатываются, т.е. удалил вообще форму - результат тот же
p.s. допёр - сделано в обычных формах, хотя написано 8.2 думал на управляемых
35. Maxim Kovalevsky (Maximysis) 8 06.03.15 06:34 Сейчас в теме
(8) adminfo2002, Конечно пiZдеть проще)
36. Александр Медведев (anig99) 2500 17.04.15 14:44 Сейчас в теме
Спасибо за алгоритм. Есть небольшое дополнение. Чтобы сделать именно шапку на колонками, а не просто объединить одинаковые ячейки и не оставлять итоги по группировке слева от колонок, то можно использовать группировку полей. Вот как у меня на рисунке. Тогда при использовании доп. кода по объединению ячеек можно получить красивую таблицу с шапками колонок.

Прикрепленные файлы:
37. Сергей Ка (graZy) 14 17.04.15 15:20 Сейчас в теме
Наткнулся случайно.
я чего-то не понял (может быть реализация связана с "-5" лет назад? или связано с особыми требованиями к формату отчета)
потому как ну нет проблемы вроде с отображением группировок

настройка "расположение группировок - вместе" дает красивый результат (ну на платформе 8.3. точно, при том что по умолчанию подразумевает "вместе" и ничего настраивать не нужно)
38. Гость 22.05.15 13:49 Сейчас в теме
39. Defor 79 27.05.15 07:33 Сейчас в теме
(37) graZy,
Сейчас проверил на платформе 8.3.4.465 (другой под рукой не было), проблема осталась.

з.ы.
Проверил на 8.3.5.1383 - результат тот же. (Для проверки можно использовать отчет из загрузок например "Объединяемые заголовки для 8.2" и закомментировать вызов "ОбработатьЗаголовки(...)"
40. Сергей Ка (graZy) 14 27.05.15 14:52 Сейчас в теме
(39) Defor,

(39) Defor,
8.3.5.1119

(экперементировал на своем отчете)

рис 1 "расположение полей группировок вместе"
рис 2 "расположение полей группировок отдельно"

Прикрепленные файлы:
41. Defor 79 28.05.15 15:01 Сейчас в теме
(40) graZy,
На втором вашем рисунке как раз нужно добиться общей шапки для "кварталов" и "полугодий"
42. Сергей Ка (graZy) 14 29.05.15 12:05 Сейчас в теме
так а чем отчет на первом рисунке не устраивает??? (зачем городить рисунок 2 с объединением) --- как писал ранее, если это только не требования к форме отчета (тогда понятно зачем) - в остальных случаях рис1 по мне так идеально подходит (и все стандартными средствами СКД)
43. Dmitri Taran (demien@tut.by) 19 19.11.15 13:54 Сейчас в теме
Переработал функционал из поста 32.
Проблема в том, что если по колонкам есть уже объединенные ячейки то механизм не срабатывает.
Сделал универсальную шнягу, которая объединяет даже объединенные ячейки по списку:

// Возвращает количество объединяемых ячеек
Функция ОбъединятьЯчейки(ТабДок, индСтр, индКол, ТекстДляОбъединения)
	Ячейка = ТабДок.Область(индСтр, индКол);
	
	Если ПустаяСтрока(Ячейка.Текст) Тогда
		Возврат 0;
	КонецЕсли;
	
	Если ТекстДляОбъединения.Найти(Ячейка.Текст) = Неопределено Тогда
		Возврат 0;
	КонецЕсли;
	
	КоличествоКолонок = 0;
	Для СледКолонка = индКол+1 По ТабДок.ШиринаТаблицы Цикл
		ЯчейкаСлед = ТабДок.Область(индСтр, СледКолонка);
		//Проверяем, чтобы текст был одним из указанных в ТекстДляОбъединения
		Если Ячейка.Текст = ЯчейкаСлед.Текст ИЛИ ПустаяСтрока(ЯчейкаСлед.Текст) Тогда
			КоличествоКолонок = КоличествоКолонок + 1;
		Иначе
			Возврат КоличествоКолонок;
		КонецЕсли;	
	КонецЦикла; 
	
	Возврат КоличествоКолонок;
	
КонецФункции


// Обработка заголовков таблицы
//
// Параметры
// Табл - < Тип.ТабличныйДокумент> - Табличный документ формы
Процедура ОбработатьЗаголовки(ТабДок)
	
	ТекстДляОбъединения = Новый Массив;

	// накачиваем массив значениями текстов для анализа и объединения (замените на свое)
	Выборка = Справочники.Регионы.Выбрать();
	Пока Выборка.Следующий() Цикл
		ТекстДляОбъединения.Добавить(СокрЛП(Выборка.Наименование));
	КонецЦикла; 
	// конец
	
	ОбъединяемаяОбласть = Неопределено;
	
	//Для оптимизации здесь нужно будет ограничить высоту таблицы
	Для индСтр=1 По ТабДок.ВысотаТаблицы Цикл
		
		Для индКол=1 По ТабДок.ШиринаТаблицы Цикл
			
			// определяем количество колонок объединения
			КоличествоКолонок = ОбъединятьЯчейки(ТабДок, индСтр, индКол, ТекстДляОбъединения);
			Если КоличествоКолонок Тогда
				ТекстЗаголовка = ТабДок.Область(индСтр, индКол).Текст;
				ОбъединяемаяОбласть = ТабДок.Область(индСтр, индКол, индСтр, индКол+КоличествоКолонок);
				ОбъединяемаяОбласть.Объединить();
				ОбъединяемаяОбласть.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр;
				ОбъединяемаяОбласть.Текст = ТекстЗаголовка;
				индКол = индКол+КоличествоКолонок;
			КонецЕсли;
		КонецЦикла;
		
		// Если нашли в строке области для объединения то прекращаем дальнейшие поиски
		Если не ОбъединяемаяОбласть = Неопределено Тогда
			
			возврат;
			
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

// Вызов формирования отчета и постобработка колонок
Процедура ДействияФормыСформироватьОтчет(Кнопка)
	
	//Получаем схему из макета
	СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
	
	//Из схемы возьмем настройки по умолчанию
	//Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию;
	
	Настройки = КомпоновщикНастроек.Настройки;
	
	//Помещаем в переменную данные о расшифровке данных
	ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
	
	//Формируем макет, с помощью компоновщика макета
	КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
	
	//Передаем в макет компоновки схему, настройки и данные расшифровки
	МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных,Настройки, ДанныеРасшифровки);
	
	//Выполним компоновку с помощью процессора компоновки
	ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
	ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки,,ДанныеРасшифровки);
	
	//Очищаем поле табличного документа
	Результат = ЭлементыФормы.Результат;
	Результат.Очистить();
	
	//Выводим результат в табличный документ
	ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
	ПроцессорВывода.УстановитьДокумент(Результат);
	
	ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
	
	ОбработатьЗаголовки(Результат);
КонецПроцедуры

...Показать Скрыть
whilefor; dyuha; andreich_ru; +3 Ответить 1
44. Aleksey Ivanov (aleksey_1984) 04.02.16 08:35 Сейчас в теме
(43) demien@tut.by, (43) demien@tut.by,
Добрый день.

Что бы настройки брались пользовательские надо
вместо этого:
Настройки = КомпоновщикНастроек.Настройки;

Надо написать это:
Настройки= КомпоновщикНастроек.ПолучитьНастройки();

Взял отсюда:
http://1cskd.ru/2012/03/programmnoe-vypolnenie-skd-i-polzovatelskienastrojki/
45. Алексей Белоусов (AllexSoft) 15.02.16 16:52 Сейчас в теме
Актуально, но нормально не работает (( мне например итог по группировке не нужен вообще (на скриншоте из примера первая колонка Покупатели), так еще и 3 группировки в колонках! как этому хозяйству ума дать ? может 1С что нибудь стандартное придумало все же ?
46. Dyuha K (dyuha) 05.05.16 01:05 Сейчас в теме
Требовалось объединить более одного уровня группировки. Наваял вот. Пользуйтесь, кому надо. Спасибо авторам.
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
	Настройки = КомпоновщикНастроек.ПолучитьНастройки();
	МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
	ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
	ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных, , ДанныеРасшифровки, Истина);
	ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
	ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
	ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных, Истина);
	ДокументРезультат = ОбработатьЗаголовки(ДокументРезультат);
КонецПроцедуры

Функция ОбъединятьЯчейки(ТабДок, индСтр, индКол)
	Ячейка = ТабДок.Область(индСтр, индКол);
	ЯчейкаСлед = ТабДок.Область(индСтр, индКол+1);
	Если ПустаяСтрока(Ячейка.Текст) Тогда
		Возврат ложь
	ИначеЕсли
		Ячейка.Текст = ЯчейкаСлед.Текст
			И Ячейка.Верх = Ячейка.Низ И ЯчейкаСлед.Верх = ЯчейкаСлед.Низ Тогда
		Возврат Истина;
	Иначе
		Возврат ложь
	КонецЕсли;
КонецФункции

Функция ОбработатьЗаголовки(ТабДок)
	ВысотаФ = ТабДок.ФиксацияСверху;
	ШиринаФ = ТабДок.ФиксацияСлева;
	ОбъединяемаяОбласть = Неопределено;
	Для индСтр = -ВысотаФ По -1 Цикл
		Если ТабДок.Область(-индСтр,1).Текст = "" Тогда
			Возврат ТабДок;
		КонецЕсли; 
		НачальнаяКолонка = 0;
		Для индКол=ШиринаФ+1 По ТабДок.ШиринаТаблицы Цикл
			Если ОбъединятьЯчейки(ТабДок, -индСтр, индКол) Тогда
				Если не НачальнаяКолонка Тогда
					НачальнаяКолонка = индКол;
				КонецЕсли;
			ИначеЕсли НачальнаяКолонка Тогда
				ТекстЗаголовка = ТабДок.Область(-индСтр, индКол).Текст;
				ОбъединяемаяОбласть = ТабДок.Область(-индСтр, НачальнаяКолонка, -индСтр, индКол);
				ОбъединяемаяОбласть.Объединить();
				ОбъединяемаяОбласть.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр;
				ОбъединяемаяОбласть.Текст = ТекстЗаголовка;
				НачальнаяКолонка = 0;
			Иначе
				НачальнаяКолонка = 0;
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
	Возврат ТабДок;
КонецФункции
...Показать Скрыть

Выбираем только шапку и объединяем все, что можем.
Yarilo; hlop11; kovgard; ll13; artfa; user590008_Fallen_Lord3; whilefor; info6ps; +8 Ответить
47. Яков Коган (Yashazz) 1987 17.11.16 18:06 Сейчас в теме
Блин. Обрадовался было, что есть способ сделать это средствами СКД, а тут опять свинство под названием "поячейно курочим готовый моксель". Тьфу. Аж минуснуть захотелось.