Идею мне подсказала публикация //infostart.ru/public/84642/
Судя по описанию, там много чего интересного, но скачивать не стал - несколько напрягали сообщения об ошибках в комментариях, да и реально привлекли внимание всего две фичи: суммирование по выделенным ячейкам и кнопки управления группировками. Суммирование сразу отпало, потому что этого никак не сделать без правки формы, а моей целью было облагородить отчёты УПП с минимальным вмешательством в конфигурацию.
В итоге оказалось достаточным дописать кое-что в пяти местах модуля отчёта УниверсальныйОтчет (на самом деле достаточно в четырёх, но об этом ниже):
1. В блок определения переменных модуля дописываем две переменных:
Перем мФормаОтчета; Перем мПрефиксИмениКнопкиГруппировок;
2. В конец процедуры СформироватьОтчет дописываем создание кнопок. Кнопки создаём точно там, где будут системные, если включить заголовки, чтобы при включении ничего не двоилось и системные кнопки оказывались под нашими. И не забываем, что кроме группировок строк бывают ещё группировки колонок:
//Удаляем старые х=0; Пока х<мФормаОтчета.ЭлементыФормы.Количество() Цикл лТекЭлемент=мФормаОтчета.ЭлементыФормы[х]; Если Найти(лТекЭлемент.Имя, мПрефиксИмениКнопкиГруппировок)=1 Тогда мФормаОтчета.ЭлементыФормы.Удалить(лТекЭлемент); Иначе х=х+1; КонецЕсли; КонецЦикла; //Добавляем новые Для лчЭтап=0 По 1 Цикл //0-строки, 1-колонки лчВерх=ТабличныйДокумент.Верх+?(лчЭтап=0 И ТабличныйДокумент.КоличествоУровнейГруппировокКолонок()>1,6+ТабличныйДокумент.КоличествоУровнейГруппировокКолонок()*13,3); лчЛево=ТабличныйДокумент.Лево+лчЭтап*10+?(лчЭтап=1 И ТабличныйДокумент.КоличествоУровнейГруппировокСтрок()>1,6+ТабличныйДокумент.КоличествоУровнейГруппировокСтрок()*13,3); Для х=1 По ?(лчЭтап=0,ТабличныйДокумент.КоличествоУровнейГруппировокСтрок(),ТабличныйДокумент.КоличествоУровнейГруппировокКолонок()) Цикл лКнопка=мФормаОтчета.ЭлементыФормы.Добавить(Тип("Кнопка"),мПрефиксИмениКнопкиГруппировок+?(лчЭтап=0,"Строк","Колонок")+х); лКнопка.Верх=лчВерх+лчЭтап*13*(х-1); лКнопка.Лево=лчЛево+(1-лчЭтап)*13*(х-1); лКнопка.Высота=11; лКнопка.Ширина=11; лКнопка.Шрифт=Новый Шрифт(лКнопка.Шрифт,,6); лКнопка.Заголовок=""+х; лКнопка.УстановитьДействие("Нажатие",мДействиеПолеВводаЗначениеПриИзменении); лКнопка.УстановитьПривязку(ГраницаЭлементаУправления.Верх,ТабличныйДокумент,ГраницаЭлементаУправления.Верх); лКнопка.УстановитьПривязку(ГраницаЭлементаУправления.Лево,ТабличныйДокумент,ГраницаЭлементаУправления.Лево); лКнопка.УстановитьПривязку(ГраницаЭлементаУправления.Низ,ТабличныйДокумент,ГраницаЭлементаУправления.Верх); лКнопка.УстановитьПривязку(ГраницаЭлементаУправления.Право,ТабличныйДокумент,ГраницаЭлементаУправления.Лево); КонецЦикла; КонецЦикла;
3. Для размещения кнопок на форме нам нужна сама форма, а в процедуру СформироватьОтчет она не передаётся, поэтому надо запомнить её в переменной, созданной на этапе 1. Для этого размещаем одну строку в начале процедуры ФормаПриОткрытии:
мФормаОтчета=Форма;
4. Кнопки могут работать только тогда, когда процедура-обработчик находится в модуле формы, но я не хотел менять все 100500 форм отчётов, поэтому оставалось воспользовался той процедурой, которая уже есть в этих формах и которая подходит по прототипу. Я взял ЗначениеПриИзменении. В самое начало этой процедуры надо добавить обработку нажатия наших кнопок:
Если Найти(Элемент.Имя,мПрефиксИмениКнопкиГруппировок+"Строк")=1 Тогда Форма.ЭлементыФормы[мИмяЭлементаУправленияПолеТабличногоДокументаРезультат].ПоказатьУровеньГруппировокСтрок(Число(Элемент.Заголовок)-1); Возврат; КонецЕсли; Если Найти(Элемент.Имя,мПрефиксИмениКнопкиГруппировок+"Колонок")=1 Тогда Форма.ЭлементыФормы[мИмяЭлементаУправленияПолеТабличногоДокументаРезультат].ПоказатьУровеньГруппировокКолонок(Число(Элемент.Заголовок)-1); Возврат; КонецЕсли;
5. В раздел инициализации модуля добавляем строчку, инициализирующую переменную мПрефиксИмениКнопкиГруппировок. Можно, конечно, обойтись и без этой переменной, всюду подставив её значение, но так меньше шансов сделать алгоритм неработоспособным одной опечаткой, плюс гораздо легче устранить конфликт, если вдруг случится чудо и 1С добавит в типовую конфигурацию кнопку с таким же названием:
мПрефиксИмениКнопкиГруппировок="ГМ_КнопкаГруппировок";
Не спрашивайте, почему "ГМ_..." - так надо
UPD от 27.04.2015: Появляется занятный глюк, который может стоить зря потраченных нервов: если открыть в 1С:Предприятии внешний отчёт на основе Универсального отчёта, закрыть, открыть его же в Конфигураторе и что-то поменять в его коде, то эффекта от изменений вы не увидите, пока не перезайдёте в 1С:Предприятие.
Я решил, что дело в том, что форма этого отчёта запоминается в переменной модуля Универсального отчёта. Что именно приводит к тому, что при каждом последующем открытии файла внешнего отчёта 1С вызывает к жизни тот старый фантом, я ещё не продедуктил, да это и неважно, ибо всё вылечивается, если добавить в конец процедуры ФормаПриЗакрытии модуля Универсального отчёта строку:
мФормаОтчета=Неопределено;