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