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