При разработке внешних печатных форм (ВПФ) на управляемых формах часто возникает ситуация, когда перед формированием печатного листа пользователю нужно задать какой-либо уточняющий параметр. Это может быть выбор ответственного лица, установка даты или ввод дополнительного комментария, который не хранится в самом документе. В этом случае тип команды печатной формы меняется на открытие формы. Однако возникает вопрос: как внутри этой формы «увидеть» те документы, из которых она была вызвана?
В данной статье мы разберем механизмы Библиотеки стандартных подсистем (БСП), которые отвечают за передачу данных в форму внешней обработки, и проанализируем различные способы реализации этой задачи.
Прежде всего, нам необходимо правильно описать структуру СведенияОВнешнейОбработке в модуле объекта. Именно здесь мы указываем системе, как именно должна запускаться наша обработка. Рассмотрим пример кода, где мы регистрируем команду с типом «Открытие формы».
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
ПараметрыРегистрации.Наименование = "Печатная форма с параметрами";
// Добавляем назначение (к каким документам подходит печатная форма)
ПараметрыРегистрации.Назначение.Добавить("Документ.РеализацияТоваровУслуг");
// Описываем команду
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = "Печать с уточнением данных";
НоваяКоманда.Идентификатор = "ПечатьСПараметром";
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыОткрытиеФормы();
НоваяКоманда.ПоказыватьОповещение = Истина;
Возврат ПараметрыРегистрации;
КонецФункции
Обратите внимание на ТипКомандыОткрытиеФормы(). Это критически важно, так как именно этот флаг заставляет БСП открывать основную форму обработки вместо немедленного вызова серверного метода печати.
Когда БСП открывает форму внешней обработки, она автоматически передает в нее структуру параметров. Одним из ключевых параметров является ОбъектыНазначения — это массив ссылок на документы, которые были выделены пользователем в списке или открыты в текущем окне.
Рассмотрим, как правильно извлечь эти данные в модуле формы. Разберем по шагам работу серверного события ПриСозданииНаСервере.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Проверяем наличие параметра в структуре
Если Параметры.Свойство("ОбъектыНазначения") Тогда
// Сохраняем массив объектов в реквизит формы для дальнейшего использования
// Важно помнить, что это всегда МАССИВ, даже если выбран один документ
МассивДокументов = Параметры.ОбъектыНазначения;
Если МассивДокументов.Количество() > 0 Тогда
// Для примера выведем информацию о первом документе в заголовке
ДокументСсылка = МассивДокументов[0];
ЭтаФорма.Заголовок = "Печать для: " + Строка(ДокументСсылка);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Важный нюанс: Если ваша форма предназначена для массовой печати, всегда обрабатывайте весь массив ОбъектыНазначения, а не только первый элемент. Проанализируем ситуацию: пользователь выделил 10 документов в списке и нажал кнопку печати. Если в коде прописано обращение только к индексу [0], остальные 9 документов будут проигнорированы.
Существует более гибкий вариант, который часто предпочитают опытные разработчики. В регистрации обработки указывается тип ВызовКлиентскогоМетода. В этом случае управление передается в экспортную процедуру модуля формы ВыполнитьКоманду.
Преимущество этого метода в том, что массив ОбъектыНазначения передается напрямую в процедуру как аргумент. Выясним, как это выглядит в коде модуля формы:
&НаКлиенте
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения) Экспорт
// Параметры уже здесь! Нам не нужно доставать их из структуры параметров формы.
Если ИдентификаторКоманды = "ПечатьСПараметром" Тогда
// Мы можем сначала задать вопрос пользователю
// А можем сразу открыть текущую форму модально или через описание оповещения
ПараметрыОткрытия = Новый Структура;
ПараметрыОткрытия.Вставить("ДокументыДляПечати", ОбъектыНазначения);
ОткрытьФорму("ВнешняяОбработка.ИмяВашейОбработки.Форма.ИмяВашейФормы", ПараметрыОткрытия);
КонецЕсли;
КонецПроцедуры
Этот способ позволяет реализовать сложную логику: например, проверить состояние документов на клиенте еще до того, как форма будет полностью инициализирована на сервере.
При разработке внешних форм следует учитывать несколько критически важных моментов, связанных с безопасностью и стандартами 1С:
ПараметрыРегистрации.БезопасныйРежим = Ложь;.ДополнительныеОтчетыИОбработки. Это полезно, если вам нужно прочитать макеты или настройки, сохраненные внутри карточки обработки в базе данных.ПечатьДокументов. Это обеспечит единообразный интерфейс (возможность выбора принтера, количества копий и т.д.).Когда пользователь заполнил данные в форме и нажал кнопку «Сформировать», нам нужно вызвать серверный метод для генерации табличного документа. Рассмотрим пример реализации:
&НаКлиенте
Процедура СформироватьПечать(Команда)
// Вызываем серверную функцию формирования
ТабДок = СформироватьПечатнуюФормуНаСервере(МассивДокументов, ВыбранныйПараметр);
// Выводим результат пользователю через стандартную форму печати
ПараметрыОткрытия = Новый Структура;
ПараметрыОткрытия.Вставить("ИмяМенеджераПечати", "ВнешняяОбработка.ИмяВашейОбработки");
ПараметрыОткрытия.Вставить("ТабличныеДокументы", ТабДок);
ОткрытьФорму("ОбщаяФорма.ПечатьДокументов", ПараметрыОткрытия);
КонецПроцедуры
Подводя итог, можно сказать, что механизм передачи объектов назначения в управляемых формах достаточно прозрачен, если понимать архитектуру БСП. Основным способом является обращение к Параметры.ОбъектыНазначения в событии ПриСозданииНаСервере, либо использование типа запуска ВызовКлиентскогоМетода для получения данных напрямую в процедуру ВыполнитьКоманду. Выбор конкретного способа зависит от сложности бизнес-логики вашей печатной формы.