Содержание:
Файлы материала
Описание
Уже не первый раз попадается задача, когда нужно объединить строки отчета по повторяющимся полям и решил написать универсальную процедуру, с помощь которой можно было бы легко это сделать:

Даная процедура ОбъединитьСтрокиПоКлючевымПолям вызывается после программного формирования отчета в процедуре «ПриКомпоновкеРезультата», аналогичная пост-обработка результата рассматривалась в статье Объединение заголовка колонок в отчете на СКД.
- В первом параметре ДокументРезультат— передается табличный документ с сформированным отчетом.
- В качестве второго параметра процедуры КлючевыеПоляСтрокой указывается через запятую список полей по которым необходимо выполнить объединение строк. Порядок полей влияет на группировку, т.е. каждое следующее поле объединяется в рамках предыдущего.
- В третьем и четвертом параметре НомерСтрокиЗаголовка, НомерСтрокиСДанными указываем номера строк с которых начинаются заголовок таблицы и данные соответственно.
- Пятый параметр ШагСтроки не обязательный, нужен для макетов, когда данные повторяются через несколько строк.
Реализация
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
#Область ОбработчикиСобытий &НаСервере Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) СтандартнаяОбработка = Ложь; //Макет компоновки КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки); //Компоновка данных ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных; ПроцессорКомпоновки.Инициализировать(МакетКомпоновки); //Вывод результата ДокументРезультат.Очистить(); ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент; ПроцессорВывода.УстановитьДокумент(ДокументРезультат); ПроцессорВывода.Вывести(ПроцессорКомпоновки); ОбъединитьСтрокиПоКлючевымПолям(ДокументРезультат, "Подразделение, Должность", 1, 2); КонецПроцедуры #КонецОбласти #Область СлужебныеПроцедурыИФункции // Объединение строк табличного документа по повторяющимся ключевым полям // // Параметры: // ДокументРезультат - ТабличныйДокумент - Табличный документ с сформированным отчетом // КлючевыеПоляСтрокой - Строка - Список полей указанных через запятую, по которым проводиться объединение строк // НомерСтрокиЗаголовка- Число - Номер строки табличного документа с полями заголовка таблицы // НомерСтрокиСДанными - Число - Номер строки табличного документа с первой строкой данных // ШагСтрок - Число - Шаг, через который идет следующая строка с данными // Процедура ОбъединитьСтрокиПоКлючевымПолям(ДокументРезультат, КлючевыеПоляСтрокой, НомерСтрокиЗаголовка, НомерСтрокиСДанными, ШагСтрок = 1) Экспорт Если Не ЗначениеЗаполнено(КлючевыеПоляСтрокой) Или Не ЗначениеЗаполнено(НомерСтрокиЗаголовка) Или Не ЗначениеЗаполнено(НомерСтрокиСДанными) Тогда Возврат; КонецЕсли; // преобразование строки в массив строк в нижнем регистре КлючевыеПоля = СтрРазделить(КлючевыеПоляСтрокой, ",", Ложь); Для Индекс = 0 По КлючевыеПоля.ВГраница() Цикл КлючевыеПоля[Индекс] = НРег(СокрЛП(КлючевыеПоля[Индекс])); КонецЦикла; Если Не КлючевыеПоля.Количество() Тогда Возврат; КонецЕсли; ДанныеПоКлючевымПолям = Новый ТаблицаЗначений; ДанныеПоКлючевымПолям.Колонки.Добавить("КлючевоеПоле", ОбщегоНазначения.ОписаниеТипаСтрока(150)); ДанныеПоКлючевымПолям.Колонки.Добавить("НомерКолонки", ОбщегоНазначения.ОписаниеТипаЧисло(3)); // поиск колонок табличного документа по ключевым полям СчетчикКолонок = 1; Пока СчетчикКолонок < ДокументРезультат.ШиринаТаблицы Цикл ТекстЯчейки = ДокументРезультат.Область(НомерСтрокиЗаголовка, СчетчикКолонок, НомерСтрокиЗаголовка, СчетчикКолонок).Текст; Если ЗначениеЗаполнено(ТекстЯчейки) Тогда ТекстЯчейки = СокрЛП(НРег(ТекстЯчейки)); ИндексКлючевогоПоля = КлючевыеПоля.Найти(ТекстЯчейки); Если ИндексКлючевогоПоля <> Неопределено Тогда НоваяСтрока = ДанныеПоКлючевымПолям.Добавить(); НоваяСтрока.КлючевоеПоле = КлючевыеПоля[ИндексКлючевогоПоля]; НоваяСтрока.НомерКолонки = СчетчикКолонок; КонецЕсли; КонецЕсли; СчетчикКолонок = СчетчикКолонок + 1; КонецЦикла; Если КлючевыеПоля.Количество() <> ДанныеПоКлючевымПолям.Количество() Тогда // не удалось найти номера колонок для всех ключевых полей Возврат; КонецЕсли; // рекурсивное объединение строк УровеньРекурсии = 0; ОбъединитьСтрокиПоКлючевомуПолюРекурсивно(УровеньРекурсии, ДанныеПоКлючевымПолям, ДокументРезультат, НомерСтрокиСДанными, ДокументРезультат.ВысотаТаблицы, ШагСтрок); КонецПроцедуры Процедура ОбъединитьСтрокиПоКлючевомуПолюРекурсивно(Знач УровеньРекурсии, ДанныеПоКлючевымПолям, ДокументРезультат, Знач НомерПервойСтроки, Знач НомерПоследнейСтроки, Знач ШагСтрок = 1) ВыполнятьОбъединение = Ложь; ОбъединятьСтрокиС = НомерПервойСтроки; ОбъединятьСтрокиПо = НомерПервойСтроки; ПрошлоеЗначение = ""; ТекущееЗначение = ""; ЭтоПерваяСтрока = Истина; ЭтоПоследняяСтрока = Ложь; СчетчикСтрок = НомерПервойСтроки; Пока СчетчикСтрок <= НомерПоследнейСтроки Цикл ТекстЯчейки = ДокументРезультат.Область(СчетчикСтрок, ДанныеПоКлючевымПолям[УровеньРекурсии].НомерКолонки, СчетчикСтрок, ДанныеПоКлючевымПолям[УровеньРекурсии].НомерКолонки).Текст; Если ЭтоПерваяСтрока Тогда ПрошлоеЗначение = ТекстЯчейки; СчетчикСтрок = СчетчикСтрок + ШагСтрок; ЭтоПерваяСтрока = Ложь; Продолжить; Иначе ТекущееЗначение = ТекстЯчейки; КонецЕсли; ЭтоПоследняяСтрока = СчетчикСтрок = НомерПоследнейСтроки; Если ТекущееЗначение = ПрошлоеЗначение Тогда ВыполнятьОбъединение = Истина; СчетчикСтрок = СчетчикСтрок + ШагСтрок; Если Не ЭтоПоследняяСтрока Тогда Продолжить; КонецЕсли; КонецЕсли; // объединение строк Если ВыполнятьОбъединение Тогда ОбъединятьСтрокиПо = СчетчикСтрок - 1; ДокументРезультат.Область(ОбъединятьСтрокиС, ДанныеПоКлючевымПолям[УровеньРекурсии].НомерКолонки, ОбъединятьСтрокиПо, ДанныеПоКлючевымПолям[УровеньРекурсии].НомерКолонки).Объединить(); // новый виток рекурсии СледующийУровень = УровеньРекурсии + 1; Если СледующийУровень < ДанныеПоКлючевымПолям.Количество() Тогда ОбъединитьСтрокиПоКлючевомуПолюРекурсивно(СледующийУровень, ДанныеПоКлючевымПолям, ДокументРезультат, ОбъединятьСтрокиС, ОбъединятьСтрокиПо, ШагСтрок); КонецЕсли; ВыполнятьОбъединение = Ложь; КонецЕсли; ОбъединятьСтрокиС = СчетчикСтрок; ПрошлоеЗначение = ТекущееЗначение; СчетчикСтрок = СчетчикСтрок + ШагСтрок; КонецЦикла; КонецПроцедуры #КонецОбласти |
В начале статьи можно скачать отчет в котором реализован данный пример.
