Как работают внешние печатные формы в 1С: разбираемся с ДанныеПечати, СсылкаНаОбъект и модулем менеджера

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

Разработка внешних печатных форм (ВПФ) — одна из наиболее частых задач для программиста 1С. Использование механизма ВПФ позволяет изменять печатные формы документов без изменения самой конфигурации, что существенно облегчает последующие обновления системы. Однако у начинающих разработчиков часто возникают вопросы при анализе кода типовых ВПФ. В частности: откуда берется загадочный параметр ДанныеПечати, где физически находится запрос к базе данных и почему в некоторых обработках используется реквизит СсылкаНаОбъект, а в других его нет?

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

Что такое параметр ДанныеПечати и откуда он берется?

При изучении кода заполнения печатных форм (например, ТОРГ-12, М-15 или УПД) мы часто встречаем процедуры следующего вида:

Процедура ЗаполнитьРеквизитыШапкиТОРГ12(ДанныеПечати, Макет, ТабличныйДокумент)

Внутри этой процедуры происходит обращение к свойствам параметра ДанныеПечати так, будто это сам документ: ДанныеПечати.Организация, ДанныеПечати.Грузополучатель, ДанныеПечати.НомерДокумента и так далее. Из-за этого может возникнуть ошибочное мнение, что в параметр передается ссылка на сам документ или его объектная форма. Но это не так.

На самом деле параметр ДанныеПечати — это строка выборки из результата запроса (объект ВыборкаИзРезультатаЗапроса) либо строка таблицы значений (или структура), содержащая подготовленные к выводу данные. Давайте разберем подробнее, почему разработчики БСП используют именно такой подход:

  1. Производительность системы. Если бы система получала данные напрямую через обращение к реквизитам ссылки (например, СсылкаНаДокумент.Организация.ИНН), то при печати группового пакета документов из 100 штук платформа совершила бы сотни или даже тысячи отдельных запросов к базе данных. Это привело бы к критическому снижению производительности.
  2. Пакетная выборка. Механизм печати БСП сначала собирает массив всех документов, отправленных на печать, а затем выполняет один мощный пакетный запрос к базе данных. Этот запрос собирает сразу все необходимые сведения: юридические адреса, банковские реквизиты контрагентов, ФИО ответственных лиц, коды ОКПО и информацию по табличным частям.
  3. Обход выборки в цикле. Результат этого пакетного запроса передается в цикл обхода. На каждой итерации цикла текущая строка выборки передается в процедуру заполнения областей макета.

Таким образом, в процедуру ЗаполнитьРеквизитыШапкиТОРГ12 передается уже готовый набор данных по конкретному документу из общего пула запроса, что минимизирует обращения к серверу СУБД.

Почему во внешней печатной форме нет текста запроса? Взаимодействие с модулем менеджера

Часто при открытии кода ВПФ разработчики обнаруживают, что в модуле объекта самой обработки вообще нет ни одного SQL-подобного запроса к базе данных. Возникает вопрос: каким образом печатная форма получает данные, если самого запроса внутри нее нет?

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

Проанализируем типичный сценарий работы ВПФ "ТОРГ-12" для документа "Реализация товаров и услуг":

  1. При вызове печати внешняя обработка обращается к конфигурации и вызывает метод из модуля менеджера документа. Например:
    
    ДанныеДляПечати = Документы.РеализацияТоваровУслуг.ПолучитьДанныеДляПечатиТОРГ12(МассивОбъектов);
    
  2. Этот метод выполняет сложный оптимизированный запрос внутри самой конфигурации, формирует структуру данных и возвращает ее обратно во внешнюю печатную форму.
  3. ВПФ принимает готовые таблицы и выборки, обходит их в цикле и выводит в табличный документ, используя локальный макет.

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

Недостатки: Если вам требуется кардинально изменить состав выводимых данных (например, добавить во ВПФ реквизиты, которых вообще нет в стандартной выборке модуля менеджера), вам придется отказаться от переиспользования типового метода и написать собственный запрос к базе данных внутри модуля объекта ВПФ.

Загадочная СсылкаНаОбъект: старый и новый стандарты БСП

В сообщениях на форумах часто упоминается реквизит СсылкаНаОбъект. Разберем, откуда он берется и почему его поведение различается в зависимости от версии БСП.

Здесь мы сталкиваемся с эволюцией стандартов разработки подсистемы "Печать" в Библиотеке стандартных подсистем.

Старый стандарт БСП (до версии 2.x)

В устаревших конфигурациях механизм подключения ВПФ требовал обязательного создания реквизита на уровне метаданных внешней обработки. Этот реквизит должен был называться строго СсылкаНаОбъект (тип ЛюбаяСсылка).

Алгоритм работы платформы выглядел следующим образом:

  1. Пользователь нажимал кнопку "Печать".
  2. Система БСП находила подключенную внешнюю обработку в справочнике "Дополнительные отчеты и обработки".
  3. Создавался объект внешней обработки в памяти сервера.
  4. В созданный реквизит СсылкаНаОбъект программно записывалась ссылка на печатаемый документ.
  5. Затем вызывалась экспортная функция Печать() модуля объекта ВПФ, которая не принимала параметров. Внутри кода этой функции разработчик обращался к данным через конструкцию: ДокументСсылка = ЭтотОбъект.СсылкаНаОбъект;

Современный стандарт БСП (версии 2.x и 3.x)

В современных конфигурациях 1С (ERP, УТ 11, КА 2, БП 3.0, ЗУП 3) механизм полностью переведен на передачу параметров через вызовы процедур на сервере без использования реквизитов обработки. Создавать реквизит СсылкаНаОбъект в метаданных обработки больше не требуется.

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


Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт

Рассмотрим назначение ключевых параметров этой процедуры:

Пошаговое руководство: как спроектировать ВПФ правильно

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

Шаг 1. Определение стратегии получения данных

Перед написанием кода нам необходимо решить, откуда мы будем брать данные для заполнения макета:

Шаг 2. Создание внешней обработки

Создаем новую внешнюю обработку в конфигураторе. Нам не нужно создавать никаких реквизитов в метаданных. Переходим сразу в модуль объекта обработки и объявляем обязательную функцию регистрации внешней обработки в системе БСП:


Функция СведенияОВнешнейОбработке() Экспорт
    
    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
    
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидДополнительногоОтчетаИОбработкиПечатнаяФорма();
    ПараметрыРегистрации.Версия = "1.0";
    ПараметрыРегистрации.Наименование = "Внешняя печатная форма ТОРГ-12 (Кастомная)";
    ПараметрыРегистрации.БезопасныйРежим = Ложь; // Если используем сложные запросы или внешние компоненты
    
    // Указываем, к каким документам конфигурации привязывается печатная форма
    ПараметрыРегистрации.Назначение.Добавить("Документ.РеализацияТоваровУслуг");
    
    // Описываем команду печати
    НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
    НоваяКоманда.Представление = "ТОРГ-12 (внешняя кастомная)";
    НоваяКоманда.Идентификатор = "ТОРГ12_Кастомная";
    НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
    НоваяКоманда.Модификатор = "ПечатьMXL";
    
    Возврат ПараметрыРегистрации;
    
КонецФункции

Шаг 3. Реализация экспортной процедуры Печать

Добавим в модуль объекта процедуру Печать, которая будет вызываться системой БСП при нажатии пользователем кнопки на панели команд:


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

Шаг 4. Написание запроса и заполнение макета

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


Процедура СформироватьПечатнуюФорму(МассивОбъектов, ТабличныйДокумент, ОбъектыПечати)
    
    // Получаем макет из нашей внешней обработки
    Макет = ПолучитьМакет("МакетТОРГ12");
    
    // Инициализируем запрос к базе данных
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   Реализация.Ссылка КАК Ссылка,
        |   Реализация.Номер КАК НомерДокумента,
        |   Реализация.Дата КАК ДатаДокумента,
        |   Реализация.Организация КАК Организация,
        |   Реализация.Контрагент КАК Контрагент,
        |   Реализация.Организация.НаименованиеПолное КАК ОрганизацияПредставление,
        |   Реализация.Контрагент.НаименованиеПолное КАК КонтрагентПредставление
        |ИЗ
        |   Документ.РеализацияТоваровУслуг КАК Реализация
        |ГДЕ
        |   Реализация.Ссылка В (&МассивОбъектов)";
    
    Запрос.УстановитьПараметр("МассивОбъектов", МассивОбъектов);
    
    // Выполняем запрос и обходим результаты
    РезультатЗапроса = Запрос.Выполнить();
    ВыборкаДокументов = РезультатЗапроса.Выбрать();
    
    ПервыйДокумент = Истина;
    
    Пока ВыборкаДокументов.Следующий() Цикл
        
        Если Не ПервыйДокумент Тогда
            // Разрываем страницы между документами
            ТабличныйДокумент.ВывестиГоризонтальныйРазделительСтраниц();
        КонецЕсли;
        ПервыйДокумент = Ложь;
        
        // Запоминаем начальную строку для объектов печати
        НомерСтрокиНачало = ТабличныйДокумент.ВысотаТаблицы + 1;
        
        // Здесь ВыборкаДокументов и выступает в роли "ДанныеПечати"
        ВывестиШапкуТОРГ12(ВыборкаДокументов, Макет, ТабличныйДокумент);
        ВывестиТабличнуюЧастьТОРГ12(ВыборкаДокументов.Ссылка, Макет, ТабличныйДокумент);
        ВывестиПодвалыТОРГ12(ВыборкаДокументов, Макет, ТабличныйДокумент);
        
        // Регистрируем область печати для БСП
        УправлениеПечатью.ЗадатьОбластьПечатиДокумента(ТабличныйДокумент, НомерСтрокиНачало, ОбъектыПечати, ВыборкаДокументов.Ссылка);
        
    КонецЦикла;
    
КонецПроцедуры

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

Отладка внешних печатных форм: практические советы

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

  1. Использование внешней обработки как обычной. На время разработки создайте на управляемой форме обработки временную кнопку, по нажатию на которую будет выполняться код:
    
    &НаКлиенте
    Процедура ТестПечати(Команда)
        
        МассивДокументов = Новый Массив;
        МассивДокументов.Добавить(ПолучитьСсылкуНаТестовыйДокумент());
        
        ТабличныйДокумент = Новый ТабличныйДокумент;
        ОбъектыПечати = Новый Соответствие;
        
        СформироватьПечатнуюФорму(МассивДокументов, ТабличныйДокумент, ОбъектыПечати);
        ТабличныйДокумент.Показать();
        
    КонецПроцедуры
    
    Это позволит вам отлаживать логику формирования запросов и заполнения макета обычным нажатием кнопки F5 без постоянной перезаписи обработки в справочник "Дополнительные отчеты и обработки".
  2. Отключение безопасного режима. При регистрации обработки в справочнике снимите флаг "Безопасный режим". В безопасном режиме отладчик 1С иногда игнорирует точки останова внутри модулей объектов внешних обработок.
  3. Использование специализированных обработок отладки. На профильных ресурсах для разработчиков существуют готовые внешние обработки (например, "Отладчик внешних печатных форм"), которые эмулируют поведение механизмов БСП и позволяют запускать ВПФ в контексте отладки в один клик.

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

← На главную