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