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