gifts2017

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

Опубликовал 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.

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

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

См. также

Подписаться Добавить вознаграждение

Комментарии

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


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

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

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

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

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

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

		Возврат Ложь

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

	Иначе

		Возврат Ложь

	КонецЕсли;

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

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

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

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

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

(39) Defor,
8.3.5.1119

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

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

Прикрепленные файлы:
41. Defor 28.05.15 15:01
(40) graZy,
На втором вашем рисунке как раз нужно добиться общей шапки для "кварталов" и "полугодий"
42. Сергей Ка (graZy) 29.05.15 12:05
так а чем отчет на первом рисунке не устраивает??? (зачем городить рисунок 2 с объединением) --- как писал ранее, если это только не требования к форме отчета (тогда понятно зачем) - в остальных случаях рис1 по мне так идеально подходит (и все стандартными средствами СКД)
43. Dmitri Taran (demien@tut.by) 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;
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
	Возврат ТабДок;
КонецФункции
...Показать Скрыть

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