При выводе печатных форм на принтер разработчики и пользователи периодически сталкиваются с ситуацией, когда в режиме предварительного просмотра документ отображается ровно на одной странице, но при физической печати или отправке в виртуальный принтер устройство протягивает второй пустой лист. Эта проблема особенно критична при печати на бланках строгой отчетности (например, листах нетрудоспособности или ПТС), где порча бланка недопустима. Разберем по шагам причины такого поведения платформы 1С:Предприятие и Библиотеки стандартных подсистем (БСП), а также рассмотрим программные способы гарантированного устранения дефекта.
Выясним причину, из-за которой табличный документ начинает занимать две страницы вместо одной:
ОбластьПечати в механизмах БСП: При печати через стандартную подсистему «Печать» формируется объект ПакетОтображаемыхДокументов. В процессе подготовки документов БСП выполняет поэтапное копирование печатных форм через вспомогательные функции. Стандартная функция ЗаполнитьЗначенияСвойств() вместе со списком копируемых свойств табличного документа не переносит свойство ОбластьПечати. Если макет содержал служебные колонки за пределами заданной области печати, они принудительно отправляются на принтер.ОбластьПечати: Данное свойство принимает только объект типа ОбластьЯчеекТабличногоДокумента, принадлежащий строго текущему экземпляру табличного документа. Попытка скопировать область напрямую из исходного макета или формы без перепривязки к новому документу сбрасывает настройку.ИмяПараметровПечати, 1С автоматически подгружает сохраненные пользователем параметры страницы (поля, ориентацию, масштаб). Пользовательские настройки переопределяют программные директивы модуля.Рассмотрим подробнее код подсистемы печати БСП. При формировании пакета отображаемых документов происходит создание новых табличных документов методом ПолучитьОбласть() или Вывести(). Чтобы не потерять границы области печати, необходимо явно переносить координаты ячеек на результирующий табличный документ.
Посмотрим на пример доработки функции формирования табличных документов на форме печати:
&НаСервере
Функция ТабличныеДокументыДляПечати()
ТабличныеДокументы = Новый СписокЗначений;
Для Каждого НастройкаПечатнойФормы Из НастройкиПечатныхФорм Цикл
Если Элементы[НастройкаПечатнойФормы.ИмяРеквизита].Вывод = ИспользованиеВывода.Разрешить И НастройкаПечатнойФормы.Печатать Тогда
ПечатнаяФорма = ЭтотОбъект[НастройкаПечатнойФормы.ИмяРеквизита];
ТабличныйДокумент = Новый ТабличныйДокумент;
ТабличныйДокумент.Вывести(ПечатнаяФорма);
ЗаполнитьЗначенияСвойств(ТабличныйДокумент, ПечатнаяФорма, УправлениеПечатью.КопируемыеСвойстваТабличногоДокумента());
// Явный перенос области печати на созданный документ
Если ПечатнаяФорма.ОбластьПечати <> Неопределено Тогда
ТабличныйДокумент.ОбластьПечати = ТабличныйДокумент.Область(
ПечатнаяФорма.ОбластьПечати.Верх,
ПечатнаяФорма.ОбластьПечати.Лево,
ПечатнаяФорма.ОбластьПечати.Низ,
ПечатнаяФорма.ОбластьПечати.Право
);
КонецЕсли;
ТабличныйДокумент.КоличествоЭкземпляров = НастройкаПечатнойФормы.Количество;
ТабличныеДокументы.Добавить(ТабличныйДокумент, НастройкаПечатнойФормы.Представление);
КонецЕсли;
КонецЦикла;
Возврат ТабличныеДокументы;
КонецФункции
Проанализируем второй участок в общем модуле УправлениеПечатью, где формируется ПакетОтображаемыхДокументов. При разделении печатных форм на комплекты через метод ПолучитьОбласть() также требуется заново назначить область:
// Фрагмент функции ПакетДокументов в общем модуле УправлениеПечатью
ТабличныйДокумент = ПечатнаяФорма.ПолучитьОбласть(Область.Верх, , Область.Низ);
ЗаполнитьЗначенияСвойств(ТабличныйДокумент, ПечатнаяФорма, КопируемыеСвойстваТабличногоДокумента());
Если ПечатнаяФорма.ОбластьПечати <> Неопределено Тогда
ТабличныйДокумент.ОбластьПечати = ТабличныйДокумент.Область(
1,
ПечатнаяФорма.ОбластьПечати.Лево,
ТабличныйДокумент.ВысотаТаблицы,
ПечатнаяФорма.ОбластьПечати.Право
);
КонецЕсли;
ПакетОтображаемыхДокументов.Состав.Добавить().Данные = ПакетСОднимТабличнымДокументом(ТабличныйДокумент);
Если печать выполняется на бланках строгого позиционирования, где нельзя использовать автоподгонку масштаба (свойство АвтоМасштаб искажает расположение ячеек), необходимо программно контролировать количество формируемых страниц перед отправкой на принтер.
Разберем реализацию проверки числа страниц с помощью метода КоличествоСтраниц():
// Отключение влияния сохраненных параметров пользователя
ТабличныйДокумент.ИмяПараметровПечати = "";
// Установка параметров страницы
ТабличныйДокумент.ПолеСлева = 0;
ТабличныйДокумент.ПолеСправа = 0;
ТабличныйДокумент.ПолеСверху = 0;
ТабличныйДокумент.ПолеСнизу = 0;
ТабличныйДокумент.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;
// Проверка количества страниц
Если ТабличныйДокумент.КоличествоСтраниц() > 1 Тогда
// Если документ не поместился по ширине, программно поджимаем крайние технические колонки
Для НомерКолонки = 1 По 3 Цикл
ТабличныйДокумент.Область(, НомерКолонки, , НомерКолонки).ШиринаКолонки =
Макс(0.5, ТабличныйДокумент.Область(, НомерКолонки, , НомерКолонки).ШиринаКолонки - 0.2);
КонецЦикла;
КонецЕсли;
Для узкоспециализированных печатных форм (больничные листы, сертификаты, штрихкодовые этикетки) эффективным решением является отказ от использования пакетной печати БСП в пользу прямого вывода через метод Напечатать() объекта ТабличныйДокумент.
Посмотрим, как организовать прямую отправку готового табличного документа на принтер без диалога:
Процедура НапечататьБланкНаПринтере(ТабличныйДокумент, ИмяЦелевогоПринтера)
// Указываем конкретный принтер, настроенный под физические параметры бланка
ТабличныйДокумент.ИмяПринтера = ИмяЦелевогоПринтера;
// Задаем строгие размеры без автомасштабирования
ТабличныйДокумент.АвтоМасштаб = Ложь;
ТабличныйДокумент.МасштабПечати = 100;
// Печать без открытия диалогового окна
ТабличныйДокумент.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);
КонецПроцедуры
Для предотвращения смещения макетов при обновлениях платформы рекомендуется соблюдать следующие правила проектирования табличных документов:
ВысотаСтроки должно быть задано в явном виде, а для свойства АвтоВысотаСтроки установлено значение Ложь.Обрезать вместо Переносить или Авто, чтобы непредвиденно длинные строки не увеличивали высоту секций.ИмяПараметровПечати: При формировании уникальных бланков строгой отчетности всегда очищайте свойство ИмяПараметровПечати, чтобы старые настройки полей из пользовательского кэша не переопределяли программно заданные нулевые поля.