Данная публикация имеет две основные цели
- Зафиксировать полученный опыт, чтобы через некоторое время можно было его использовать повторно
- Получить обратную связь от сообщества относительно предлагаемых приемов. Альтернативные решения крайне приветствуются
1. Объединение, скрытие, замена
Пусть требуется получить отчет следующего вида
Этот отчет имеет несколько особенностей:
- Объединенные ячейки в шапке
- Количество и состав колонок в группе “Бонусы” - динамические. Выводятся только, если заполнено хотя бы для одного сотрудника в отчете. Если, например, никто из попавших в отчет сотрудников не получил надбавку за сверхурочные, то этой колонки в отчете быть не должно. Проектов в группе “за проекты” может быть неограниченное количество.
- Дополнительные требования к порядку полей: колонка “Оклад” должна выводиться первой, “Всего по сотруднику” - последней
В консоли можно получить следующий результат
Далее приведены универсальные процедуры, с помощью которых можно:
1. Объединить ячейки “Бонусы” и “За проекты” в шапке отчета с помощью процедуры ОбъединтьЯчейкиВТабличномДокументе()
2. Скрыть заголовок ресурса “Сумма” с помощью процедуры СкрытьСтрокиВТабличномДокументе()
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ВывестиСКДВТабличныйДокумент(СхемаКомпоновкиДанных, ДокументРезультат, КомпоновщикНастроек);
Маркер = "Бонусы";
ОбъединитьЯчейкиВТабличномДокументе(ДокументРезультат, Маркер);
Маркер = "За проекты";
ОбъединитьЯчейкиВТабличномДокументе(ДокументРезультат, Маркер);
Маркер = "Сумма";
СкрытьСтрокиВТабличномДокументе(ДокументРезультат, Маркер);
КонецПроцедуры
Процедура ОбъединитьЯчейкиВТабличномДокументе(ТабличныйДокумент, МаркерОбъединения) Экспорт
// Находит ячейки, содержащие в тексте МаркерОбъединения
// Объединяет ячейки, располагающиеся рядом, содержащие одинаковый текст и маркер объединения
ОбъединяемыеЯчейки = НайтиОбластиТабличногоДокументаПоВхождениюПодстроки(ТабличныйДокумент, МаркерОбъединения);
ОбъединяемыеЯчейки.Колонки.Добавить("Диапазон");
ОбъединяемыеЯчейки.Сортировать("Верх,Лево");
Для Каждого Строка из ОбъединяемыеЯчейки Цикл
Отбор = Новый Структура("Текст,Верх,Лево", Строка.Текст, Строка.Верх-1, Строка.Лево);
НайденныеСтроки = ОбъединяемыеЯчейки.НайтиСтроки(Отбор);
Если НайденныеСтроки.Количество() Тогда
Строка.Диапазон = НайденныеСтроки[0].Диапазон;
Строка.Диапазон.Низ = Макс(Строка.Диапазон.Низ, Строка.Верх);
Продолжить;
КонецЕсли;
Отбор = Новый Структура("Текст,Верх,Лево", Строка.Текст, Строка.Верх, Строка.Лево-1);
НайденныеСтроки = ОбъединяемыеЯчейки.НайтиСтроки(Отбор);
Если НайденныеСтроки.Количество() Тогда
Строка.Диапазон = НайденныеСтроки[0].Диапазон;
Строка.Диапазон.Право = Макс(Строка.Диапазон.Право, Строка.Лево);
Продолжить;
КонецЕсли;
Строка.Диапазон = Новый Структура("Текст,Верх,Лево,Низ,Право", Строка.Текст, Строка.Верх, Строка.Лево, Строка.Верх, Строка.Лево);
КонецЦикла;
ОбъединяемыеЯчейки.Свернуть("Диапазон");
Для Каждого Строка Из ОбъединяемыеЯчейки Цикл
Диапазон = Строка.Диапазон;
Область = ТабличныйДокумент.Область(Диапазон.Верх, Диапазон.Лево, Диапазон.Низ, Диапазон.Право);
Область.Объединить();
КонецЦикла;
КонецПроцедуры
Процедура ЗаменитьТекстВТабличномДокументе(ТабличныйДокумент, ПодстрокаПоиска, ПодстрокаЗамены) Экспорт
НайденныеОбласти = НайтиОбластиТабличногоДокументаПоВхождениюПодстроки(ТабличныйДокумент, ПодстрокаПоиска);
Для каждого Строка из НайденныеОбласти Цикл
Строка.Область.Текст = СтрЗаменить(Строка.Область.Текст, ПодстрокаПоиска, ПодстрокаЗамены);
КонецЦикла;
КонецПроцедуры
Процедура СкрытьСтрокиВТабличномДокументе(ТабличныйДокумент, МаркерУдаления) Экспорт
НайденныеОбласти = НайтиОбластиТабличногоДокументаПоВхождениюПодстроки(ТабличныйДокумент, МаркерУдаления);
НайденныеОбласти.Свернуть("Верх");
Для каждого Строка из НайденныеОбласти Цикл
Область = ТабличныйДокумент.Область(Строка.Верх, , Строка.Верх, );
Область.Видимость = Ложь;
КонецЦикла;
КонецПроцедуры
Функция НайтиОбластиТабличногоДокументаПоВхождениюПодстроки(ТабличныйДокумент, ПодстрокаПоиска) Экспорт
НайденныеОбласти = Новый ТаблицаЗначений;
НайденныеОбласти.Колонки.Добавить("Область");
НайденныеОбласти.Колонки.Добавить("Текст");
НайденныеОбласти.Колонки.Добавить("Верх");
НайденныеОбласти.Колонки.Добавить("Лево");
НайденнаяОбласть = ТабличныйДокумент.НайтиТекст(ПодстрокаПоиска);
Пока НЕ НайденнаяОбласть = Неопределено Цикл
НоваяСтрока = НайденныеОбласти.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, НайденнаяОбласть);
НоваяСтрока.Область = НайденнаяОбласть;
НайденнаяОбласть = ТабличныйДокумент.НайтиТекст(ПодстрокаПоиска, НайденнаяОбласть);
КонецЦикла;
Возврат НайденныеОбласти;
КонецФункции
2. Процедуры по выводу табличного документа
Эти процедуры можно найти в различных интерпретациях на множестве сайтов. Здесь выкладываю те, которые использую я
Процедура ВывестиСКДВТабличныйДокумент(МакетСКД, ТабличныйДокумент, КомпоновщикНастроек = Неопределено)
Если КомпоновщикНастроек = Неопределено Тогда
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
КомпоновщикНастроек.ЗагрузитьНастройки(МакетСКД.НастройкиПоУмолчанию);
КонецЕсли;
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(МакетСКД, Настройки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабличныйДокумент);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
// Пример вызова из отчета
//Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
//
// СтандартнаяОбработка = Ложь;
// ПрограммнаяРаботаССКД.ВывестиСКДВТабличныйДокумент(СхемаКомпоновкиДанных, ДокументРезультат, КомпоновщикНастроек);
//
//КонецПроцедуры
КонецПроцедуры
Функция ПолучитьТаблицуЗначенийИзСКД(МакетСКД, КомпоновщикНастроек) Экспорт
Результат = Новый ТаблицаЗначений;
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(МакетСКД, Настройки,,,
Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(Результат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Возврат Результат;
КонецФункции
3. Вывод рядом двух независимых таблиц
Данная идея была взята с форума (отличный пример выложил ditp). Моя заслуга лишь в том, чтобы обернуть ее в функцию и незначительно оптимизировать.
Функция ПрисоединитьТабличныйДокументКТабличномуДокументу(ТабличныйДокументОсновной, ТабличныйДокументПрисоединяемый)
// идея взята с форума: http://forum.infostart.ru/forum86/topic157420/message1610993/#message1610993
ТабличныйДокументОбъединенный = Новый ТабличныйДокумент;
Область = ТабличныйДокументОсновной.ПолучитьОбласть(1,1, ТабличныйДокументОсновной.ВысотаТаблицы, ТабличныйДокументОсновной.ШиринаТаблицы);
ТабличныйДокументОбъединенный.Вывести(Область);
ТабличныйДокументОбъединенный.Присоединить(ТабличныйДокументПрисоединяемый);
Возврат ТабличныйДокументОбъединенный;
КонецФункции
4. Установка собственного формата для табличного документа
Данная процедура является оберткой над стандартной процедурой СоздатьФорматСтрок() (постоянно приходится вспоминать, как она называется). Позволяет выводить одну таблицу под другой с независимой шириной колонок. В сводном примере данная процедура применяется для корректного форматирования конечного документа
Процедура ЗадатьФорматСтрокВТабличномДокументе(пТабличныйДокумент)
// задает индивидуальный формат строк для табличного документа, сохраняя ширину колонок при выводе его в другой табличный документ
пТабличныйДокумент.Область(1,,пТабличныйДокумент.ВысотаТаблицы).СоздатьФорматСтрок();
КонецПроцедуры
Процедуры тестировались на платформе 8.3 в режиме совместимости с 8.2 и без режима совмместимости, а также на платформе 8.1.
К статье прилагаются внешние отчеты со сводным примером (запускается в любой конфигурации 8.2/8.3 на обычных или управляемых формах, также отчет на 8.1)