Как доработать типовую печатную форму в 1С через Расширение без создания внешней печатной формы?

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

При сопровождении и доработке конфигураций 1С перед разработчиком часто встает задача изменения печатных форм. Традиционный подход с созданием Внешней печатной формы (ВПФ) имеет свои недостатки: необходимость постоянного обновления кода при изменении структуры метаданных, неудобство отладки и дополнительные сложности при работе в безопасном режиме. С развитием механизма расширений в платформе 1С:Предприятие 8.3 появился более элегантный и надежный способ — доработка типового макета и логики его формирования непосредственно в расширении. Это позволяет оставить основную конфигурацию на полной поддержке и упростить дальнейшие обновления.

В этой статье мы подробно и по шагам разберем, как доработать типовую печатную форму (на примере документа «Акт сверки взаимных расчетов»), добавив в нее собственные данные и изменив макет, используя только возможности расширений.

Внешняя печатная форма или Расширение: что выбрать?

Прежде чем перейти к практической реализации, проанализируем, почему доработка через расширение во многих случаях предпочтительнее создания ВПФ:

  1. Простота и удобство отладки. Отладка кода в расширении происходит точно так же, как и в основной конфигурации. Вам не нужно загружать файлы обработки во временные хранилища или использовать специализированные внешние отладчики.
  2. Интеграция с интерфейсом. Через расширение легко управлять расположением команды печати в меню (например, вывести форму на самую первую позицию), управлять видимостью команд в зависимости от прав и ролей пользователей.
  3. Доступ к серверному контексту. Расширения работают в едином контексте с базой данных, что исключает проблемы с передачей сложных типов данных между клиентом и сервером.
  4. Устойчивость при обновлениях. Заимствуя только необходимые процедуры получения данных и переопределяя их точечно, мы минимизируем риск того, что печатная форма «сломается» после очередного релиза конфигурации.

Рассмотрим детально процесс доработки типовой печатной формы на примере добавления контактных данных ответственного менеджера в подвал Акта сверки взаимных расчетов.

Шаг 1. Подготовка расширения и заимствование объектов

Для начала создадим новое расширение (или откроем существующее) и заимствуем в него необходимые объекты:

  1. Документ, печатную форму которого мы планируем изменить (в нашем случае — Документ.АктСверкиВзаимныхРасчетов).
  2. Типовой макет печатной формы (например, ПФ_MXL_АктСверкиВзаимныхРасчетов).
  3. Модуль менеджера заимствованного документа, так как именно в нем по стандартам БСП (Библиотеки стандартных подсистем) располагается логика формирования печатных форм.

После переноса макета в расширение мы можем открыть его интерактивно и добавить новую область или отредактировать существующие параметры. В нашем примере мы добавим новый параметр КонтактыМенеджера в область подвала макета.

Шаг 2. Добавление команды печати в меню документа

Если нам необходимо добавить новую команду печати или переопределить поведение существующей, мы можем использовать предопределенные процедуры БСП в модуле менеджера документа. Используем директиву &После для перехвата процедуры добавления команд печати.

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


&После("ДобавитьКомандыПечати")
Процедура зсп_ДобавитьКомандыПечати(КомандыПечати) Экспорт
    
    // Создаем новую команду печати для нашего измененного акта сверки
    КомандаПечати = КомандыПечати.Добавить();
    КомандаПечати.Идентификатор = "АктСверкиСКонтактами";
    КомандаПечати.Представление = НСтр("ru = 'Акт сверки (с контактами менеджера)'");
    КомандаПечати.Обработчик = "УправлениеПечатьюБПКлиент.ВыполнитьКомандуПечати";
    КомандаПечати.СписокФорм = "ФормаСписка,ФормаВыбора,ФормаДокумента";
    КомандаПечати.Порядок = 1; // Устанавливаем команду в самый верх списка
    
КонецПроцедуры

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

Шаг 3. Изменение параметров формирования данных (Директива &Вместо)

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

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

Разберем конкретный пример модификации структуры настроек печати в модуле менеджера документа:


&Вместо("ВыборкаДанныхДокумента")
Функция зсп_ВыборкаДанныхДокумента(МассивОбъектов, НастройкиПечати)
    
    // Вызываем оригинальный алгоритм для первоначального заполнения настроек
    РезультатНастроек = ПродолжитьВызов(МассивОбъектов, НастройкиПечати);
    
    // Добавляем в структуру настроек путь к нужным нам данным
    // В данном случае указываем поле получения контактов менеджера
    НастройкиПечати.Вставить("КонтактыМенеджера", "ДокументСверки.Ответственный.ФизическоеЛицо.КонтактнаяИнформация.Представление");
    
    Возврат РезультатНастроек;
    
КонецФункции

Шаг 4. Модификация текста запроса получения данных

Часто данные для печатной формы собираются сложным динамическим запросом. Переписывать его полностью — плохая практика, так как при обновлении конфигурации структура таблиц может измениться. Оптимальный вариант — использовать замену текста запроса «на лету» с помощью функции СтрЗаменить().

Проанализируем пример доработки функции формирования текста запроса:


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

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

Шаг 5. Тонкая доработка табличного документа (Альтернативный вариант)

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

Этот подход особенно удобен, когда нужно просто дописать несколько строк в подвал документа или прикрепить дополнительную небольшую область.

Рассмотрим пример реализации такого алгоритма:


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

Такой подход делает наше решение максимально устойчивым к обновлениям: основной макет и алгоритм получения данных остаются полностью на поддержке поставщика, а мы лишь дополняем готовый табличный документ своей областью из изолированного макета расширения.

Резюме и рекомендации

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

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

← На главную