При разработке печатных форм часто возникает задача: перед тем как вывести документ на экран, нужно запросить у пользователя дополнительные параметры, например, дату и номер приказа, которые не хранятся в самом документе. Начинающие разработчики часто сталкиваются с тем, что после закрытия окна ввода данных печатная форма просто не открывается. Проанализируем ситуацию, выясним причину ошибки и разберем по шагам правильный алгоритм реализации этой задачи в среде 1С:Предприятие 8.3 на управляемых формах.
Рассмотрим типичную ошибку, которую допускают многие: в форме ввода параметров (назовем ее ФормаНомерДата) в обработчике команды «ОК» прописывается вызов процедуры закрытия формы, а следом — вызов процедуры формирования печатной формы. На первый взгляд логика кажется верной, но в управляемом приложении она ошибочна. Разберем почему:
ЭтаФорма.Закрыть(), текущая форма и весь ее программный контекст по сути перестают существовать для платформы. Любой код, написанный после этой команды в той же процедуре, может либо не выполниться вовсе, либо выполниться некорректно.Чтобы реализовать корректный вызов, мы должны применить механизм обратного вызова (callback). Суть метода заключается в том, что при открытии формы ввода параметров мы передаем ей специальный объект ОписаниеОповещения. Этот объект «говорит» системе: «Когда эта форма закроется, вызови вот эту конкретную процедуру в основной форме и передай ей результат».
Разберем реализацию по шагам.
В форме документа, где пользователь нажимает кнопку «Печать», мы должны перехватить стандартную обработку и открыть наше окно параметров. Посмотрим на пример кода в модуле основной формы:
&НаКлиенте
Процедура Подключаемый_ВыполнитьКомандуПечати(Команда)
// Создаем описание оповещения, указывающее на процедуру "ПослеВводаПараметров"
// в этом же модуле
Оповещение = Новый ОписаниеОповещения("ПослеВводаПараметров", ЭтаФорма);
// Открываем форму ввода номера и даты
// Параметры открытия можно оставить пустыми или передать текущий объект
ОткрытьФорму("Документ.НашДокумент.Форма.ФормаНомерДата", , ЭтаФорма, , , , Оповещение);
КонецПроцедуры
Теперь проанализируем, что должно происходить в форме ФормаНомерДата. Нам нужно просто собрать введенные данные в структуру и закрыть форму, передав эту структуру в качестве параметра метода Закрыть().
&НаКлиенте
Процедура Ок(Команда)
// Проверяем заполнение данных
Если Не ЗначениеЗаполнено(Дата) Тогда
Сообщить("Введите дату!");
Возврат;
КонецЕсли;
// Формируем структуру с данными
РезультатВыбора = Новый Структура;
РезультатВыбора.Вставить("Номер", Номер);
РезультатВыбора.Вставить("Дата", Дата);
// Закрываем форму и передаем структуру обратно в оповещение
Закрыть(РезультатВыбора);
КонецПроцедуры
После того как форма ФормаНомерДата закроется, управление автоматически перейдет в процедуру, которую мы указали в ОписаниеОповещения. Именно здесь мы инициируем формирование печатной формы. Посмотрим, как это выглядит в модуле основной формы:
&НаКлиенте
Процедура ПослеВводаПараметров(Результат, ДополнительныеПараметры) Экспорт
// Если пользователь просто закрыл окно (нажал крестик), Результат будет Неопределено
Если Результат = Неопределено Тогда
Возврат;
КонецЕсли;
// Теперь у нас есть данные в Результат.Номер и Результат.Дата
// Вызываем серверную процедуру печати
СформироватьПечатнуюФормуНаСервере(Результат);
КонецПроцедуры
&НаСервере
Процедура СформироватьПечатнуюФормуНаСервере(ПараметрыПечати)
// Здесь мы уже можем вызывать стандартные механизмы БСП
// Или обращаться к менеджеру документа
МассивОбъектов = Новый Массив;
МассивОбъектов.Добавить(Объект.Ссылка);
// Если используется стандартная подсистема печати БСП:
// ПараметрыПечати передаются в коллекцию или используются для заполнения макета
// Вызываем процедуру Печать из модуля менеджера или общего модуля
// Документы.НашДокумент.Печать(МассивОбъектов, ..., ПараметрыПечати);
КонецПроцедуры
В современных конфигурациях 1С (ЗУП 3.1, БП 3.0, ERP) процедура Печать в общем модуле или модуле менеджера обычно принимает 4 обязательных параметра: МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати и ПараметрыВывода.
Важный момент: Чтобы ваши номер и дата попали в макет, у вас есть два пути:
ПараметрыВывода своими значениями. Однако, чаще всего эти данные используются непосредственно внутри логики формирования табличного документа.ПараметрыПечати и передать ее в серверную процедуру. Внутри серверной процедуры Печать, когда вы будете обходить МассивОбъектов, вы просто подставите значения из этой структуры в соответствующие области макета.Пример заполнения области макета с использованием переданных данных:
// Внутри серверной функции формирования печатной формы
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
// Номер и Дата - это те самые данные из нашей структуры Результат
ОбластьШапка.Параметры.НомерПриказа = ДополнительныеПараметры.Номер;
ОбластьШапка.Параметры.ДатаПриказа = ДополнительныеПараметры.Дата;
ТабДок.Вывести(ОбластьШапка);
Чтобы избежать ошибок при формировании печатной формы с промежуточным вводом данных, всегда придерживайтесь правила: форма ввода данных ничего не знает о печати. Ее задача — только получить данные от пользователя и передать их «наверх» (вызывающей форме) через механизм оповещений. Вся ответственность за запуск процесса печати лежит на форме документа или команде печати, которая дожидается закрытия диалога и обрабатывает его результат.
Используя этот подход, вы обеспечите стабильную работу кода во всех режимах работы 1С:Предприятия и сможете легко масштабировать логику печати, добавляя новые параметры ввода без риска «потерять» контекст выполнения программы.