При разработке внешних печатных форм (ВПФ) на базе Библиотеки стандартных подсистем (БСП) разработчики часто сталкиваются с задачей: при нажатии кнопки сохранения печатной формы на диск или отправке по электронной почте имя файла должно формироваться динамически (например, содержать вид документа, его номер и дату), а не дублировать системное наименование макета или команды печати.
Рассмотрим, почему стандартное свойство платформы ИспользуемоеИмяФайла не срабатывает в типовых конфигурациях, разберем типичные ошибки и посмотрим на правильные способы программной установки имени сохраняемого файла.
Проанализируем две распространенные ошибки, которые не приносят ожидаемого результата при работе с типовыми подсистемами печати:
ТабДок.ИспользуемоеИмяФайла: данное платформенное свойство учитывается только при вызове прямого показа табличного документа методом ТабличныйДокумент.Показать() или через системное меню «Файл — Сохранить как...». Типовая подсистема БСП открывает форму предварительного просмотра (ОбщаяФорма.ПечатьДокументов), которая полностью перехватывает сохранение и генерирует имена файлов из параметров коллекции печатных форм.УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию ожидает строковое значение либо объект Соответствие. Если передать туда ссылку на объект напрямую (тип ДокументСсылка), подсистема БСП не сможет обработать этот тип и подставит синоним макета по умолчанию.ОбъектыПечати: если при выводе областей табличного документа не вызывается регистрация областей конкретных документов, механизм сохранения не может сопоставить сформированные страницы с исходными объектами базы данных.Если печатная форма формируется строго для одного документа или для всех выбранных документов выводится общий табличный документ с единым именем, достаточно явно привести представление документа к строковому типу и передать в седьмой параметр метода УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию.
Посмотрим на пример реализации в процедуре формирования печатных форм:
// Формируем строковое наименование файла сохранения
ИмяФайла = Строка(МассивОбъектов[0]);
// Выводим сформированный табличный документ в коллекцию БСП
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"Макет_ЗаказаКлиента",
"Заказ клиента",
ТабличныйДокумент,
,
,
ИмяФайла
);
Разберем универсальный и наиболее правильный подход по стандартам БСП, поддерживающий как одиночную, так и групповую печать нескольких документов в один табличный документ с возможностью раздельного сохранения каждого файла.
Для этого выполним следующие шаги:
Соответствие, в котором ключом будет ссылка на документ, а значением — формируемое имя файла для сохранения.УправлениеПечатью.ЗадатьОбластьПечатиДокумента.Посмотрим на пример полного кода функции печати:
Функция СформироватьПечатныеФормы(МассивОбъектов, ОбъектыПечати, КоллекцияПечатныхФорм) Экспорт
ТабличныйДокумент = Новый ТабличныйДокумент;
ТабличныйДокумент.АвтоМасштаб = Истина;
// Создаем соответствие для индивидуальных имен файлов
ИменаФайлов = Новый Соответствие;
Макет = ПолучитьМакет("Макет_ЗаказаКлиента");
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ПервыйДокумент = Истина;
Для Каждого Ссылка Из МассивОбъектов Цикл
Если Не ПервыйДокумент Тогда
ТабличныйДокумент.ВывестиГоризонтальныйРазделительСтраниц();
КонецЕсли;
ПервыйДокумент = Ложь;
// Фиксируем номер первой строки текущего документа в табдоке
НомерСтрокиНачало = ТабличныйДокумент.ВысотаТаблицы + 1;
// Заполняем и выводим области макета
ОбластьШапка.Параметры.Заполнить(Ссылка);
ТабличныйДокумент.Вывести(ОбластьШапка);
// Регистрируем область печати для текущего объекта
УправлениеПечатью.ЗадатьОбластьПечатиДокумента(
ТабличныйДокумент,
НомерСтрокиНачало,
ОбъектыПечати,
Ссылка
);
// Формируем понятное имя файла для сохранения/отправки
ИмяФайлаДокумента = "Заказ клиента № " + ПрефиксацияОбъектовКлиентСервер.НомерНаПечать(Ссылка.Номер);
ИменаФайлов.Вставить(Ссылка, ИмяФайлаДокумента);
КонецЦикла;
// Передаем соответствие имен файлов седьмым параметром
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"Макет_ЗаказаКлиента",
"Заказ клиента",
ТабличныйДокумент,
,
,
ИменаФайлов
);
Возврат ТабличныйДокумент;
КонецФункции
Рассмотрим альтернативный вариант: если вывод табличного документа уже реализован стандартным вызовом, имя файла сохранения можно задать или переопределить через строку коллекции печатных форм перед завершением работы процедуры.
Посмотрим на пример кода:
// Получаем строку сведений о сформированной печатной форме
СведенияОФорме = УправлениеПечатью.СведенияОПечатнойФорме(КоллекцияПечатныхФорм, "Макет_ЗаказаКлиента");
Если СведенияОФорме <> Неопределено Тогда
// Присваиваем строку или соответствие ссылок и строк
СведенияОФорме.ИмяФайлаПечатнойФормы = ИменаФайлов;
КонецЕсли;
Обратим внимание на критически важные моменты при генерации строки имени файла:
Строка(Ссылка) в строку часто попадает дата с двоеточиями (например, 12:00:00) или номера со слэшами. Символы \ / : * ? " < > | запрещены файловой системой и вызовут ошибку при сохранении. Для безопасной очистки строки рекомендуется использовать типовую функцию БСП ФайловыеФункцииКлиентСервер.КорректноеИмяФайла().ПрефиксацияОбъектовКлиентСервер.НомерНаПечать(Ссылка.Номер).