Постобработка отчёта СКД — это доработка готового табличного документа кодом после того, как система компоновки данных его сформировала. Она нужна, когда настройками СКД нужный вид не получить: колонка с картинками товаров, строка с номерами колонок под шапкой, особые заголовки группировок, колонтитулы, разрыв страницы по каждому контрагенту. Чтобы добраться до результата, отчёт формируют программно — в обработчике ПриКомпоновкеРезультата модуля отчёта или через СкомпоноватьРезультат из формы.
Ниже — оба способа, шаблон программного формирования, поэлементный вывод и пять примеров, которые я регулярно применяю в доработках.
Когда постобработка действительно нужна
Прежде чем писать код, проверьте, не решается ли задача настройками: условное оформление, параметры вывода на закладке «Другие настройки», макеты полей и группировок в схеме. Постобработка — это код, который придётся поддерживать, и он ломается при изменении структуры отчёта.
| Задача | Без кода | С постобработкой |
|---|---|---|
| Цвет и шрифт по условию | Условное оформление | Не нужна |
| Свой текст заголовка колонки | Заголовок поля, макет поля | Только для нетиповых шапок |
| Картинки в ячейках | Поле-картинка в актуальных версиях платформы | Особое размещение, масштаб |
| Нумерация колонок под шапкой | Нет | Да |
| Колонтитулы, повтор шапки при печати | Нет | Да |
| Разрыв страницы по группировке | Нет | Да |
Два способа перехватить формирование отчёта
Способ 1: своя команда в форме отчёта
Стандартную кнопку «Сформировать» заменяют своей командой. В ней вызывают метод формы СкомпоноватьРезультат в режиме Непосредственно, а затем дорабатывают реквизит Результат.
Минусы: отчёту нужна своя форма, формирование идёт синхронно (без фонового режима), а постобработку почти всегда приходится уносить на сервер отдельным вызовом. Для разовой задачи сойдёт, для типового решения — нет.
Способ 2: обработчик ПриКомпоновкеРезультата
В модуле объекта отчёта есть предопределённый обработчик ПриКомпоновкеРезультата. Если в нём отключить стандартную обработку, вся компоновка выполняется вашим кодом на сервере, и результат можно доработать до того, как его увидит пользователь. Работает и с формой по умолчанию, и с фоновым формированием.

Шаблон программного формирования отчёта СКД
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ДокументРезультат.Очистить();
// Итоговые настройки: вариант + пользовательские + фиксированные.
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
// Дальше — постобработка готового документа.
ДобавитьНумерациюКолонок(ДокументРезультат);
КонецПроцедурыВажные моменты:
ДанныеРасшифровкипередавайте и в компоновщик макета, и в процессор — иначе пропадёт расшифровка по двойному клику.- Настройки берите через
ПолучитьНастройки(), а не напрямую изКомпоновщикНастроек.Настройки, иначе пользовательские отборы не применятся. - Четвёртый параметр
Инициализироватьразрешает использовать в выражениях схемы функции общих модулей; если они не нужны, его можно не передавать.
Поэлементный вывод
Вместо Вывести можно выводить результат по элементам. Это позволяет вмешаться в процесс: пропустить элемент, вставить что-то между ними, посчитать свои итоги.
ПроцессорВывода.НачатьВывод();
Пока Истина Цикл
ЭлементРезультата = ПроцессорКомпоновки.Следующий();
Если ЭлементРезультата = Неопределено Тогда
Прервать;
КонецЕсли;
// Здесь можно анализировать ЭлементРезультата и выводить дополнительные области.
ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
КонецЦикла;
ПроцессорВывода.ЗакончитьВывод();Поэлементный вывод сложнее в отладке: элементы — это фрагменты макета, а не строки отчёта. Я использую его, только когда постобработка готового документа не подходит.
Пример 1: картинки товаров в прайс-листе
Идея: в отчёт выводится поле со ссылкой на номенклатуру, после формирования проходим по строкам, через расшифровку достаём значение поля и вставляем рисунок в ячейку.
// Вставляет картинки номенклатуры в указанную колонку отчёта.
Процедура ВставитьКартинкиНоменклатуры(ДокументРезультат, ДанныеРасшифровки, НомерКолонки, ВысотаШапки)
Для НомерСтроки = ВысотаШапки + 1 По ДокументРезультат.ВысотаТаблицы Цикл
Ячейка = ДокументРезультат.Область(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки);
Если ТипЗнч(Ячейка.Расшифровка) <> Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
Продолжить;
КонецЕсли;
ПоляРасшифровки = ДанныеРасшифровки.Элементы[Ячейка.Расшифровка].ПолучитьПоля();
ПолеНоменклатуры = ПоляРасшифровки.Найти("Номенклатура");
Если ПолеНоменклатуры = Неопределено Тогда
Продолжить;
КонецЕсли;
ДанныеКартинки = ПолучитьДанныеКартинки(ПолеНоменклатуры.Значение); // своя функция
Если ДанныеКартинки = Неопределено Тогда
Продолжить;
КонецЕсли;
ДокументРезультат.Область(НомерСтроки, , НомерСтроки).ВысотаСтроки = 50;
Рисунок = ДокументРезультат.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
Рисунок.Картинка = Новый Картинка(ДанныеКартинки);
Рисунок.РазмерКартинки = РазмерКартинки.Пропорционально;
Рисунок.Расположить(Ячейка);
Ячейка.Текст = "";
КонецЦикла;
КонецПроцедурыФункция ПолучитьДанныеКартинки зависит от конфигурации: в типовых решениях картинка обычно хранится в присоединённом файле, и её двоичные данные получают средствами БСП. Не тяните картинки запросом в сам набор данных: тяжёлые двоичные данные замедлят компоновку.
Пример 2: нумерация колонок под шапкой
Под шапкой вставляем строку и пишем номера колонок, как в регламентных формах.
// Добавляет под шапкой строку с номерами колонок.
Процедура ДобавитьНумерациюКолонок(ДокументРезультат)
СтрокаШапки = ДокументРезультат.ФиксацияСверху;
Если СтрокаШапки = 0 Тогда
Возврат;
КонецЕсли;
ОбластьШапки = ДокументРезультат.Область(СтрокаШапки, , СтрокаШапки);
ОбластьВставки = ДокументРезультат.Область(СтрокаШапки + 1, , СтрокаШапки + 1);
ДокументРезультат.ВставитьОбласть(ОбластьШапки, ОбластьВставки,
ТипСмещенияТабличногоДокумента.ПоВертикали, Ложь);
Для НомерКолонки = 1 По ДокументРезультат.ШиринаТаблицы Цикл
Ячейка = ДокументРезультат.Область(СтрокаШапки + 1, НомерКолонки);
Ячейка.Текст = Формат(НомерКолонки, "ЧГ=0");
Ячейка.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр;
Ячейка.Расшифровка = Неопределено;
КонецЦикла;
ДокументРезультат.ФиксацияСверху = СтрокаШапки + 1;
КонецПроцедурыКопируем строку шапки, чтобы унаследовать оформление и рамки, затем заменяем текст номерами. Расшифровку в новой строке обнуляем, иначе двойной клик по номеру откроет расшифровку заголовка.
Пример 3: повтор шапки и колонтитулы при печати
Для печати длинных отчётов шапку повторяют на каждой странице и добавляют колонтитулы.
// Настраивает печать: повтор шапки и верхний колонтитул.
Процедура НастроитьПечатьОтчета(ДокументРезультат, ЗаголовокОтчета)
Если ДокументРезультат.ФиксацияСверху > 0 Тогда
ДокументРезультат.ПовторятьПриПечатиСтроки =
ДокументРезультат.Область(1, , ДокументРезультат.ФиксацияСверху);
КонецЕсли;
Колонтитул = ДокументРезультат.ВерхнийКолонтитул;
Колонтитул.Выводить = Истина;
Колонтитул.НачальнаяСтраница = 2;
Колонтитул.ТекстСлева = ЗаголовокОтчета;
Колонтитул.ТекстВЦентре = "Стр. [&НомерСтраницы] из [&СтраницВсего]";
Колонтитул.ТекстСправа = "Напечатано: [&Дата] [&Время]";
КонецПроцедурыНачальнаяСтраница = 2 убирает колонтитул с первой страницы, где и так есть заголовок отчёта.
Пример 4: разрыв страницы по группировке
Типичная просьба бухгалтерии: каждый контрагент — с новой страницы. Надёжный способ без разбора макетов — сформировать отчёт во временный документ, найти строки, где начинается новая запись верхней группировки (через расшифровку, как в примере 1), а затем собрать итоговый документ по кускам:
- Вывести в итоговый документ шапку:
ДокументРезультат.Вывести(Временный.ПолучитьОбласть(1, , ВысотаШапки)). - Для каждого блока группировки вывести его область и после неё вызвать
ДокументРезультат.ВывестиГоризонтальныйРазделительСтраниц(). - Восстановить
ФиксацияСверхуи параметры печати.
Расшифровка при копировании областей сохраняется, потому что идентификаторы ссылаются на те же ДанныеРасшифровки.

Пример 5: заголовки группировок колонок
Когда в таблице несколько уровней группировок колонок, СКД выводит заголовки так, как умеет: с дублями или с лишними строками. Часть проблем снимает параметр «Расположение полей группировок» на вложенных группировках колонок. Если и этого мало, после формирования объединяют ячейки шапки (Область(...).Объединить()), переписывают тексты и удаляют пустые строки шапки. Код здесь всегда привязан к конкретной структуре варианта, поэтому я фиксирую такой вариант как предопределённый и запрещаю пользователю менять структуру.
Типичные ошибки
- Забыли
СтандартнаяОбработка = Ложь. Отчёт формируется дважды или ваш результат затирается стандартным. - Берут
КомпоновщикНастроек.Настройки. Пользовательские и фиксированные отборы игнорируются. - Жёсткие номера строк и колонок. Пользователь добавил поле — постобработка вставила картинку не туда. Ищите колонки по расшифровке или по тексту шапки.
- Постобработка на клиенте. Работа с табличным документом на клиенте по ячейкам медленная и неудобная. Всё — на сервере.
- Тяжёлые данные в наборе. Картинки и большие тексты тянут отдельно, только для выведенных строк.
Постобработка хороша, когда она тонкая: несколько точечных правок поверх отчёта, который корректно работает и без неё.
Если в отчётах накопилось много постобработки и они стали хрупкими, это повод пересобрать их по уму — в рамках разработки отчётов на СКД или доработки печатных форм 1С.
Коротко
- Постобработка — доработка готового табличного документа, для неё отчёт формируется программно.
- Основное место для кода —
ПриКомпоновкеРезультатасСтандартнаяОбработка = Ложь. - Настройки берите через
ПолучитьНастройки(),ДанныеРасшифровкипередавайте в компоновщик и процессор. - Типовые задачи: картинки, нумерация колонок, колонтитулы, разрывы страниц, сложные заголовки.
- Ищите колонки и строки по расшифровке, а не по жёстким номерам.




