Как объединить заголовки колонок в таблице
Данный пост родился в результате поиска решения проблемы из поста /2010/07/kak-v-skd-nakryt-kolonki-shapkoj/
Имеем отчет вида:
Настройки отчета:
Необходимо одинаковые заголовки группировок объединить.
Предлагаю данную операцию произвести над сформированным табличным документом, используя следующий код:
// Обработка заголовков таблицы // // Параметры // ТабДок - <ТабличныйДокумент> - Табличный документ формы Процедура ОбработатьЗаголовки(ТабДок) ОбъединяемаяОбласть = Неопределено; //Для оптимизации здесь нужно будет ограничить высоту таблицы Для индСтр=1 По ТабДок.ВысотаТаблицы Цикл НачальнаяКолонка = 0; Для индКол=1 По ТабДок.ШиринаТаблицы Цикл // определяем начало объединения Если ОбъединятьЯчейки(ТабДок, индСтр, индКол) Тогда Если не НачальнаяКолонка Тогда НачальнаяКолонка = индКол; КонецЕсли; ИначеЕсли НачальнаяКолонка Тогда // завершаем объединение ТекстЗаголовка = ТабДок.Область(индСтр, индКол).Текст; ОбъединяемаяОбласть = ТабДок.Область(индСтр, НачальнаяКолонка, индСтр, индКол); ОбъединяемаяОбласть.Объединить(); ОбъединяемаяОбласть.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр; ОбъединяемаяОбласть.Текст = ТекстЗаголовка; НачальнаяКолонка = 0; Иначе НачальнаяКолонка = 0; КонецЕсли; КонецЦикла; // Если нашли в строке области для объединения, то прекращаем дальнейшие поиски Если не ОбъединяемаяОбласть = Неопределено Тогда Возврат; КонецЕсли; КонецЦикла; КонецПроцедуры // Проверка двух смежных ячеек на идентичность Функция ОбъединятьЯчейки(ТабДок, индСтр, индКол) Ячейка = ТабДок.Область(индСтр, индКол); ЯчейкаСлед = ТабДок.Область(индСтр, индКол+1); Если ПустаяСтрока(Ячейка.Текст) Тогда Возврат ложь; ИначеЕсли Ячейка.Текст = ЯчейкаСлед.Текст // Проверяем на соответствие заголовка и Ячейка.Имя = "R"+индСтр+"C"+индКол // Проверяем на соответствие имени (отсеиваем уже объединенные ячейки) Тогда Возврат Истина; Иначе Возврат ложь КонецЕсли; КонецФункции |
Вставляем вызов после формирования табличного документа:
Результат представлен ниже:
Главный недостаток этого способа, трудно заранее определить начальную и конечную область поиска, т. к. функция может отработать и объединить любые другие смежные идентичные ячейки. Если есть идеи как однозначно идентифицировать ячейки заголовка группировок пишите. А пока этот код можно использовать с некоторыми изменения в каждом конкретном случае.
Большое спасибо за обработку, тоже самое приходилось делать на 7-ке.
Может я спроше глупость но куда вставить данную процедуру?
Вставлять после формирования результирующего табличного документа.
На http://infostart.ru/public/77916/ есть пример.
Платформа 8.2. Форма отчета управляемая, использую выше приведенные процедуры/функции в отчете следующим образом:
Модуль формы отчета:
&НаКлиенте
// Проверка двух смежных ячеек на идентичночность
Функция ОбъединятьЯчейки(ТабДок, индСтр, индКол)
Ячейка = ТабДок.Область(индСтр, индКол);
ЯчейкаСлед = ТабДок.Область(индСтр, индКол+1);
Если ПустаяСтрока(Ячейка.Текст) Тогда
Возврат ложь
ИначеЕсли Ячейка.Текст = ЯчейкаСлед.Текст //Проверяем на соответствие заголовка
и Ячейка.Имя = “R”+индСтр+”C”+индКол Тогда // Проверяем на соответствие имени (отсеиваем уже объединенные ячейки)
Возврат Истина;
Иначе
Возврат ложь
КонецЕсли;
КонецФункции
&НаКлиенте
// Обработка заголовков таблицы
//
// Параметры
// Табл – – Табличный документ формы
Процедура ОбработатьЗаголовки(ТабДок)
ОбъединяемаяОбласть = Неопределено;
Для индСтр=1 По 11 Цикл//ТабДок.ВысотаТаблицы Цикл //Для оптимизации здесь нужно будет ограничить высоту таблицы
НачальнаяКолонка = 0;
Для индКол=1 По ТабДок.ШиринаТаблицы Цикл
Если ОбъединятьЯчейки(ТабДок, индСтр, индКол) Тогда // определяем начало объединения
Если не НачальнаяКолонка Тогда
НачальнаяКолонка = индКол;
КонецЕсли;
ИначеЕсли НачальнаяКолонка Тогда // завершаем объединение
ТекстЗаголовка = ТабДок.Область(индСтр, индКол).Текст;
ОбъединяемаяОбласть = ТабДок.Область(индСтр, НачальнаяКолонка, индСтр, индКол);
ОбъединяемаяОбласть.Объединить();
ОбъединяемаяОбласть.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр;
ОбъединяемаяОбласть.Текст = ТекстЗаголовка;
НачальнаяКолонка = 0;
Иначе
НачальнаяКолонка = 0;
КонецЕсли;
КонецЦикла;
//Если не ОбъединяемаяОбласть = Неопределено Тогда // Если нашли в строке области для объединения, то прекращаем дальнейшие поиски
// возврат;
//КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура ФайловыйВариант()
ЭтаФорма.СкомпоноватьРезультат();
ОбработатьЗаголовки(Результат);
КонецПроцедуры
&НаСервере
Процедура КлиентСерверныйВариант()
ЭтаФорма.СкомпоноватьРезультат(РежимКомпоновкиРезультата.Фоновый);
КонецПроцедуры
&НаКлиенте
Процедура Сформировать(Команда)
// Вставить содержимое обработчика.
КлиентСерверныйВариант();
ОбработатьЗаголовки(Результат);
КонецПроцедуры
Проблема следующая шапка отчета выводится без объединения заголовка. При этом если процедуру КлиентСерверныйВариант() скомпоновать на кленте (&НаКлиенте), то всё объединяется как надо. Происходит как-будто затирание табличного документа серверным таб. доком. Ещё раз, после возврата с сервера происходит обработка таб.дока, но на клиенте всё равно таб.док. без объединения. Решил вынести компиляцию процедуры КлиентСерверныйВариант() на сервер, т.е. все процессы СКД протекают на сервере, а результат Таб. док. обрабатывается уже на клиенте в итоге происходит как-будто затерание обработанного результата. Подскажите в чем причина? Пробывал вынести выше приведенные процедуры/функции обработки табличного документа в модуль объекта отчета в процедуру ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) без результатно, ставил сообщалки всё нормально, т.е. исполнение кода проходит как надо, но результат заголовок таблицы без объединения.
Думаю, что одним из вариантов того, что бы обрабатывалась только область шапки можно использовать проверку на наличие данных в Элементе Результата Компоновки Данных (получаем путем обхода объекта созданного процессором компоновки данных). Как только получаем элемент содержащий какие либо данные, над вызвать обработку табличного документа (тут же можно зафиксировать шапку), а дальше просто выводим данные отчета и все. Ну, конечно, придется формировать отчет программно.