При разработке внешних печатных форм (ВПФ) в среде 1С:Предприятие 8.3 на базе Библиотеки стандартных подсистем (БСП) часто возникает задача предварительного запроса данных у пользователя. Например, при печати акта или накладной (таких как ОС-4, ОС-15) может потребоваться указать членов комиссии, причину списания или информацию о том, кто именно сдал и принял материальные ценности. Хранить эти данные непосредственно в документе не всегда целесообразно или возможно, поэтому оптимальным решением является вывод промежуточного диалогового окна (формы) перед формированием самого табличного документа.
В этой статье мы подробно разберем, как правильно перестроить стандартный механизм работы ВПФ, перевести команду печати на клиентский вызов, связать форму с модулем объекта обработки и передать введенные пользователем параметры непосредственно в печатный макет.
Проанализируем стандартный алгоритм регистрации внешней печатной формы в БСП. Обычно в функции СведенияОВнешнейОбработке разработчики указывают для команды тип использования ВызовСерверногоМетода. В этом режиме платформа сразу обращается к модулю объекта внешней обработки, находит там экспортную процедуру Печать и генерирует печатную форму на сервере, полностью минуя клиентский контекст. Соответственно, интерактивно открыть какую-либо форму для ввода реквизитов система физически не может.
Для того чтобы обойти это ограничение и показать пользователю форму настроек, нам необходимо изменить тип использования команды на ВызовКлиентскогоМетода. В таком режиме БСП сначала откроет форму нашей внешней обработки и передаст управление в ее модуль на клиенте. И уже из формы мы сможем запустить процесс формирования печатного листа.
Рассмотрим структуру функции СведенияОВнешнейОбработке в модуле объекта вашей обработки. Нам нужно найти место добавления команды в таблицу команд и изменить предпоследний параметр процедуры регистрации.
Вместо строки:
ДобавитьКоманду(ТаблицаКоманд, "ОС-15 (Саранск)", "Ос-15", "ВызовСерверногоМетода", Истина, "ПечатьMXL");
Мы должны записать команду со следующим типом использования:
ДобавитьКоманду(ТаблицаКоманд, "ОС-15 (Саранск)", "Ос-15", "ВызовКлиентскогоМетода", Истина, "ПечатьMXL");
Благодаря этому изменению система поймет, что при нажатии кнопки в меню «Печать» документа нужно выполнить клиентский сценарий внешней обработки.
Теперь перейдем к созданию основной формы внешней обработки. Добавим новую управляемую форму и назовем ее, например, ФормаПараметровПечати. Сделаем ее формой по умолчанию для нашей обработки.
Для корректной работы БСП нам обязательно нужно добавить на вкладку «Параметры» формы три ключевых параметра со строгим соблюдением их типов:
СправочникСсылка.ДополнительныеОтчетыИОбработки. Через него форма узнает ссылку на саму себя в справочнике системы.Строка. Служит для идентификации конкретного макета, если в обработке зарегистрировано несколько печатных форм.Массив (или Произвольный). Обратите внимание: для этого параметра обязательно нужно установить свойство «Ключевой». Именно через него система передаст в форму массив ссылок на документы, из которых была вызвана печать.На самой форме мы можем разместить необходимые элементы управления. В нашем примере добавим реквизит формы с именем КтоСдал (тип Строка или СправочникСсылка.ФизическиеЛица) и разместим его на форме в виде поля ввода. Также создадим команду формы Печать и вынесем ее в виде кнопки.
Когда пользователь выбирает команду печати в документе, БСП загружает форму обработки и ищет в ее модуле экспортную процедуру с именем Печать. Давайте напишем этот обработчик и сопутствующие процедуры.
Разберем по шагам код, который должен быть размещен в модуле созданной формы:
&НаКлиенте
Процедура Печать(ИдентификаторКоманды, ОбъектыНазначенияМассив) Экспорт
// Этот метод автоматически вызывается БСП при старте ВПФ.
// Наша задача — просто показать форму пользователю для заполнения полей.
ЭтотОбъект.Открыть();
КонецПроцедуры
&НаКлиенте
Процедура ПечатьНажатие(Команда) // Навешиваем этот обработчик на нашу кнопку "Печать"
// Проверим, заполнены ли критически важные для печати реквизиты на форме
Если НЕ ЗначениеЗаполнено(КтоСдал) Тогда
ПоказатьПредупреждение(, "Пожалуйста, заполните поле 'Кто сдал объект'!");
Возврат;
КонецЕсли;
// Формируем структуру с параметрами, которые мы передадим в макет
ДополнительныеПараметры = Новый Структура;
ДополнительныеПараметры.Вставить("КтоСдал", КтоСдал);
// Подготавливаем параметры для вызова стандартного механизма предварительного просмотра БСП
ПараметрыОткрытия = Новый Структура("ИсточникДанных, ПараметрыИсточника, КоллекцияПечатныхФорм");
ПараметрыОткрытия.ИсточникДанных = Параметры.ДополнительнаяОбработкаСсылка;
ПараметрыИсточника = Новый Структура("ИдентификаторКоманды, ОбъектыНазначения, ДополнительныеПараметры");
ПараметрыИсточника.ИдентификаторКоманды = Параметры.ИдентификаторКоманды;
ПараметрыИсточника.ОбъектыНазначения = Параметры.ОбъектыНазначения;
ПараметрыИсточника.ДополнительныеПараметры = ДополнительныеПараметры;
ПараметрыОткрытия.ПараметрыИсточника = ПараметрыИсточника;
// Формируем табличные документы на сервере перед выводом (требование современных версий БСП)
СформироватьПечатныеФормыНаСервере(ПараметрыОткрытия);
// Открываем стандартное окно предварительного просмотра и печати 1С
ОткрытьФорму("ОбщаяФорма.ПечатьДокументов", ПараметрыОткрытия);
// Закрываем нашу диалоговую форму параметров за ненадобностью
ЭтотОбъект.Закрыть();
КонецПроцедуры
&НаСервереБезКонтекста
Процедура СформироватьПечатныеФормыНаСервере(ПараметрыОткрытия)
Результат = Неопределено;
ОбъектыПечати = Новый СписокЗначений;
ПараметрыВывода = Неопределено;
// Вызываем системный программный интерфейс БСП для формирования табличных документов
УправлениеПечатью.ПечатьПоВнешнемуИсточнику(
ПараметрыОткрытия.ИсточникДанных,
ПараметрыОткрытия.ПараметрыИсточника,
Результат,
ОбъектыПечати,
ПараметрыВывода
);
ПараметрыОткрытия.КоллекцияПечатныхФорм = ОбщегоНазначения.ТаблицаЗначенийВМассив(Результат);
КонецПроцедуры
Теперь нам необходимо научить модуль объекта принимать переданные из формы параметры. По умолчанию стандартная процедура Печать в модуле объекта ВПФ принимает только четыре параметра. Однако БСП устроена так, что если мы передаем структуру ДополнительныеПараметры, то она автоматически пробрасывается в модуль объекта пятым необязательным параметром.
Давайте изменим заголовок и тело процедуры Печать в модуле объекта вашей внешней обработки:
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода, ДополнительныеПараметры = Неопределено) Экспорт
// Инициализируем переменную по умолчанию
КтоСдалТекст = "";
// Проверяем, пришли ли дополнительные параметры из нашей формы
Если ДополнительныеПараметры <> Неопределено Тогда
ДополнительныеПараметры.Свойство("КтоСдал", КтоСдалТекст);
КонецЕсли;
// Генерируем макет, передавая в него полученный текст подписи
ТабДок = СформироватьПечатнуюФорму(МассивОбъектов[0], ОбъектыПечати, МассивОбъектов, КтоСдалТекст);
// Выводим результат в коллекцию печатных форм для отображения на экране
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"Ос-15",
"ОС-15 (Саранск)",
ТабДок
);
КонецПроцедуры
Остается лишь скорректировать саму функцию генерации макета СформироватьПечатнуюФорму. Мы добавим в ее объявление параметр КтоСдалТекст и выведем его в нужную область табличного документа:
Функция СформироватьПечатнуюФорму(СсылкаНаОбъект, ОбъектыПечати, МассивОбъектов, КтоСдалТекст)
// ... (код инициализации макета и запроса данных из исходного текста)
// Допустим, у нас выводится область Оборот
ОбластьОборот = МакетОбработки.ПолучитьОбласть("Оборот");
ОбластьОборот.Параметры.Заполнить(ВыборкаПоШапке);
// Принудительно заполняем наш пользовательский реквизит в макете
ОбластьОборот.Параметры.КтоСдал = КтоСдалТекст;
ТабличныйДокумент.Вывести(ОбластьОборот);
// ... (завершение формирования документа)
Возврат ТабличныйДокумент;
КонецФункции
Обратим внимание на важную особенность последних редакций БСП (начиная с версии 3.1.9 и выше). Ранее при вызове формы ОбщаяФорма.ПечатьДокументов достаточно было передать только структуру ПараметрыИсточника, и генерация табличного документа происходила внутри самой общей формы печати. В современных релизах этот подход признан устаревшим.
Для обеспечения стабильной работы печатной формы на новых версиях платформы мы использовали метод УправлениеПечатью.ПечатьПоВнешнемуИсточнику на сервере (в модуле формы ВПФ), преобразовали таблицу результатов в массив структур через функцию ОбщегоНазначения.ТаблицаЗначенийВМассив() и передали готовую коллекцию в параметр КоллекцияПечатныхФорм. Это гарантирует бесперебойную работу вашего отчета во всех современных конфигурациях, таких как 1С:Бухгалтерия 3.0, ERP 2.5 или Комплексная автоматизация.
Реализовав предложенную схему, мы получаем гибкий и отказоустойчивый механизм: пользователь нажимает кнопку печати, оперативно вводит недостающие подписи или реквизиты в появившемся удобном диалоговом окне, нажимает кнопку подтверждения и сразу же видит заполненный красивый документ в стандартном окне предварительного просмотра 1С.