Почему во внешней печатной форме для УТ 10.3 не заполняются параметры макета и как это исправить?

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

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

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

Выясняем причину: почему параметры «теряются»?

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

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

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

Способ №1. Передача параметров через структуру «ДанныеДляПечати» (Рекомендуемый)

Если вам не требуется изменять структуру самого макета, а нужно лишь заполнить стандартные параметры (такие как ФИО руководителя, доверенность, должность отпускающего) своими значениями, этот способ является самым элегантным и безопасным.

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

Разберем по шагам реализацию этого механизма.

Шаг 1. Настройка интерактивной формы выбора в ВПФ.

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


Процедура КнопкаИвановНажатие(Элемент)
    РезультатВыбора = Новый Структура;
    РезультатВыбора.Вставить("ДоверенноеЛицо", "Иванов Иван Иванович");
    РезультатВыбора.Вставить("Доверенность", "По доверенности № 01/20-ШМ от 09 января 2020 года");
    
    // Закрываем форму и возвращаем структуру с данными
    ЭтаФорма.Закрыть(РезультатВыбора);
КонецПроцедуры

Шаг 2. Модальный вызов формы из модуля объекта ВПФ.

В модуле объекта ВПФ в основной функции Печать() нам необходимо открыть созданную форму модально, получить из нее структуру параметров и внедрить их в процесс печати.


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

Шаг 3. Внедрение параметров в структуру печати.

Теперь рассмотрим функцию СформироватьУПД, в которой мы получаем стандартную структуру данных для печати и дополняем ее нашими пользовательскими параметрами перед выводом на печать.


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

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

Способ №2. Локализация процедур печати в модуле объекта ВПФ (Максимальная гибкость)

Если вам требуется не просто заполнить базовые поля, но и существенно изменить сам макет (например, добавить новые строки, колонки, изменить логику компоновки областей), то предыдущий способ не подойдет, так как общий модуль все равно проигнорирует ваш встроенный макет.

В этой ситуации лучшим решением будет локализация кода. Мы полностью перенесем процедуры вывода макета из общего модуля УчетНДС в модуль объекта нашей ВПФ и перенаправим получение макета на внутренний макет обработки.

Проанализируем этот процесс детально:

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

Посмотрим на пример измененного кода вывода подвала в модуле объекта ВПФ:


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

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

Недостатки: Если фирма «1С» выпустит глобальное законодательное обновление формата УПД (изменятся колонки, ставки НДС или требования к реквизитам), вам придется вручную обновлять скопированный код внутри вашей ВПФ, сверяясь с новым кодом из общего модуля конфигурации.

Способ №3. Программная постобработка сформированного Табличного Документа

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

Суть метода заключается в том, что мы позволяем типовым механизмам полностью сформировать печатную форму УПД стандартным образом. Затем, получив готовый объект ТабличныйДокумент, мы выполняем по нему текстовый поиск и заменяем шаблонные значения на нужные нам данные прямо перед выводом на экран.

Рассмотрим, как это выглядит на практике:


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

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

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

Подведем итоги

Мы проанализировали три основных подхода к решению проблемы заполнения параметров макета во внешних печатных формах для УТ 10.3:

← На главную