Как добавить свои строки в типовой отчет 1С, не меняя его в конфигурации?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При сопровождении типовых программных продуктов на платформе 1С:Предприятие 8.3 разработчики часто сталкиваются с задачей кастомизации стандартных отчетов. При этом критически важно сохранить конфигурацию на полной поддержке поставщика, чтобы избежать сложностей при регулярных обновлениях. Модификация кода типового отчета напрямую в основной конфигурации приведет к тому, что при очередном обновлении ваши изменения могут быть затерты или потребуют сложного ручного объединения.

В данной статье мы подробно разберем профессиональные методы решения этой задачи на примере управляемых форм и Системы компоновки данных (СКД). Мы рассмотрим, как перехватывать процесс формирования отчета, программно добавлять строки с данными и использовать возможности расширений и Библиотеки стандартных подсистем (БСП).

Способ 1. Использование расширений конфигурации и перехват процедуры компоновки

Самым гибким, современным и технологичным способом является использование расширений конфигурации. Этот механизм позволяет внедриться в логику работы отчета на этапе его выполнения, не затрагивая сам объект в основной конфигурации.

Для реализации этого метода нам необходимо заимствовать модуль объекта отчета в наше расширение и перехватить стандартное событие ПриКомпоновкеРезультата. Выясним, как это сделать по шагам:

  1. Создаем новое расширение конфигурации (или используем существующее).
  2. Добавляем в расширение нужный типовой отчет (переносим только сам объект, без редактирования схемы в основной конфигурации).
  3. В расширении открываем модуль объекта заимствованного отчета и создаем обработчик события ПриКомпоновкеРезультата с аннотацией &После или &Вместо.

Проанализируем пример кода с использованием аннотации &После. В данном сценарии система сначала выполнит стандартный вывод отчета, сформирует макет и выведет его в ДокументРезультат (который является табличным документом на форме). После этого управление передается нашему коду в расширении, где мы программно дописываем нужные строки данных в конец таблицы:


&После("ПриКомпоновкеРезультата")
Процедура Расш_ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // Проверим, что отчет действительно сформирован и табличный документ не пустой
    Если ДокументРезультат.ВысотаТаблицы = 0 Тогда
        Возврат;
    КонецЕсли;
    
    // Определяем позицию для вставки. Будем выводить данные в самый конец документа
    НомерНовойСтроки = ДокументРезультат.ВысотаТаблицы + 1;
    
    // Пример добавления строки-разделителя
    ОбластьСтроки = ДокументРезультат.Область(НомерНовойСтроки, 1, НомерНовойСтроки, 5); // Диапазон колонок с 1 по 5
    ОбластьСтроки.Объединить();
    ОбластьСтроки.Текст = "--- Дополнительные аналитические данные (сформировано программно) ---";
    ОбластьСтроки.Шрифт = Новый Шрифт(ОбластьСтроки.Шрифт, , , Истина, Ложь, Ложь); // Делаем текст жирным
    ОбластьСтроки.ЦветТекста = WebЦвета.Синий;
    
    // Переходим к выводу конкретных строк с данными
    НомерНовойСтроки = НомерНовойСтроки + 1;
    
    // Заполняем ячейку с наименованием показателя
    ЯчейкаПоказатель = ДокументРезультат.Область(НомерНовойСтроки, 1);
    ЯчейкаПоказатель.Текст = "Дополнительный показатель эффективности:";
    
    // Заполняем ячейку со значением показателя
    ЯчейкаЗначение = ДокументРезультат.Область(НомерНовойСтроки, 2);
    ЯчейкаЗначение.Текст = "145.82%";
    ЯчейкаЗначение.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Право;
    
    // При необходимости можно задать рамки для новых ячеек
    ОбластьДанных = ДокументРезультат.Область(НомерНовойСтроки, 1, НомерНовойСтроки, 2);
    ОбластьДанных.Обвести(Новый Линия(ТипЛинииСеткиТабличногоДокумента.Сплошная, 1));
    
КонецПроцедуры

Способ 2. Полное управление выводом СКД через "СтандартнаяОбработка = Ложь"

Если нам необходимо не просто дописать строки в самый конец табличного документа, а встроить их непосредственно в структуру отчета (например, между группировками) или передать в компоновщик свои внешние наборы данных, то использование аннотации &После не подойдет. В этом случае мы должны полностью взять управление выводом в свои руки. Для этого используется аннотация &Вместо.

Рассмотрим подробнее шаблон кода, который отключает стандартный вывод платформы и выполняет компоновку вручную:


&Вместо("ПриКомпоновкеРезультата")
Процедура Расш_ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // Отключаем стандартный вывод отчета платформой
    СтандартнаяОбработка = Ложь;
    
    // Очищаем результирующий табличный документ перед формированием
    ДокументРезультат.Очистить();
    
    // Получаем настройки отчета
    НастройкиОтчета = КомпоновщикНастроек.ПолучитьНастройки();
    
    // Выполняем компоновку макета
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиОтчета, ДанныеРасшифровки);
    
    // Инициализируем процессор компоновки данных. 
    // Если используются внешние наборы данных, передаем их вторым параметром
    ВнешниеНаборыДанных = Новый Структура;
    // Пример: ВнешниеНаборыДанных.Вставить("ДополнительнаяТаблица", ПолучитьТаблицуДополнительныхДанных());
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки, Истина);
    
    // Выводим результат в табличный документ
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    
    // Начинаем вывод
    ПроцессорВывода.НачатьВывод();
    
    Пока Истина Цикл
        ЭлементРезультата = ПроцессорКомпоновки.Следующий();
        Если ЭлементРезультата = Неопределено Тогда
            Прервать;
        КонецЕсли;
        
        // Выводим стандартный элемент отчета
        ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
        
        // Здесь мы можем проанализировать, какой именно элемент выводится.
        // Например, если вывелась определенная группировка, мы можем программно встроить свою строку
        Если ЭлементРезультата.ЗначенияПараметров.Свойство("ИмяГруппировки") 
            И ЭлементРезультата.ЗначенияПараметров.ИмяГруппировки.Значение = "Номенклатура" Тогда
            
            // Программный вывод кастомной строки в процессе генерации отчета
            // (Реализуется через вывод областей макета или прямое добавление строк)
            
        КонецЕсли;
    КонецЦикла;
    
    ПроцессорВывода.ЗакончитьВывод();
    
КонецПроцедуры

Этот способ более трудоемок, но он предоставляет разработчику абсолютный контроль над структурой, областями и ячейками выводимого отчета.

Способ 3. Расширение формы отчета и работа с элементом управления

Иногда логику удобнее привязать не к модулю объекта отчета, а непосредственно к его форме (например, если у отчета есть уникальная форма и нам нужно модифицировать табличное поле формы сразу после того, как пользователь нажал кнопку Сформировать).

Для этого выполним следующие действия:

  1. Заимствуем форму отчета в расширение конфигурации.
  2. Находим на форме элемент управления, связанный с выводом результата (как правило, это табличное поле с именем Результат и типом ТабличныйДокумент).
  3. Перехватываем команду формирования отчета или обработчик события формы, отвечающий за заполнение панели отчетов.

Посмотрим на пример перехвата события окончания формирования отчета на форме. Во многих типовых конфигурациях на БСП используется процедура ПослеЗаполненияПанелиОтчетов или специализированные обработчики компоновки на клиенте/сервере. Если мы заимствуем форму, мы можем привязаться к процедуре, которая вызывается после завершения формирования табличного документа:


&После("ПослеЗаполненияПанелиОтчетов")
Процедура Расш_ПослеЗаполненияПанелиОтчетов()
    
    // Получаем доступ к табличному документу формы напрямую
    ТабДок = Элементы.Результат;
    
    Если ТабДок.ВысотаТаблицы > 0 Тогда
        // Выполняем постобработку ячеек формы
        Для ТекущаяСтрока = 1 По ТабДок.ВысотаТаблицы Цикл
            ОбластьЯчейки = ТабДок.Область(ТекущаяСтрока, 1);
            // Если находим нужный маркер в ячейке, модифицируем соседние данные
            Если ОбластьЯчейки.Текст = "Итого по разделу" Тогда
                // Добавим подстроку или изменим оформление
                ТабДок.Область(ТекущаяСтрока, 2).Текст = "Данные скорректированы расширением";
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
    
КонецПроцедуры

Способ 4. Внешний отчет с регистрацией в БСП и механизмом автоподмены

Если по каким-то причинам использование расширений конфигурации в вашей компании ограничено политиками безопасности или техническими регламентами, существует классический и крайне надежный способ с использованием механизмов БСП (Библиотеки стандартных подсистем).

Разберем данный алгоритм по шагам:

  1. Открываем конфигуратор и находим типовой отчет, который необходимо доработать.
  2. Сохраняем данный отчет на жесткий диск как внешний файл с расширением .erf (через меню Файл -> Сохранить как...).
  3. Открываем сохраненный внешний отчет в конфигураторе. Теперь мы можем изменять его схему компоновки, запросы, макеты и модули абсолютно любым способом. Мы можем добавить к основному запросу конструкцию ОБЪЕДИНИТЬ ВСЕ, чтобы подмешать свои виртуальные строки данных, или дописать логику в модуль объекта.
  4. После внесения всех изменений сохраняем внешний отчет.
  5. Запускаем базу данных в режиме 1С:Предприятие под правами администратора.
  6. Переходим в раздел НСИ и администрирование -> Печатные формы, отчеты и обработки -> Дополнительные отчеты и обработки.
  7. Добавляем новый элемент и выбираем наш файл внешнего отчета.
  8. В карточке регистрации отчета БСП предоставляет уникальную возможность — настроить публикацию с замещением (подменой) стандартного отчета. Мы указываем, какой именно типовой отчет из конфигурации должен быть заменен нашей внешней версией.

Результат: Для конечных пользователей ничего не меняется. Они заходят в свои привычные разделы интерфейса, нажимают стандартные кнопки вызова отчета, но система под капотом незаметно для них открывает и формирует модифицированный внешний отчет. При этом конфигурация базы данных остается полностью типовой и обновляется в автоматическом режиме без конфликтов.

Резюме

Мы проанализировали различные подходы к решению задачи изменения отчета без изменения самой конфигурации. Выбор конкретного метода зависит от архитектуры вашего решения:

← На главную