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