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