Вначале задача была просто выводить нижний колонтитул для одной страницы, обычно с изменяемой по высоте в зависимости от содержания высотой. Алгоритм был таким: функция на вход получала массив областей печати и в цикле уменьшая размер массива снизу пыталась вывести их все плюс область подвала, когда это удавалось функция в зависимости от параметров уходила в рекурсия пытаясь вывести оставшийся контент, либо завершала свою работу и возвращала массив с оставшимися не выведенными областями.
Когда решив использовать функция для вывода всего содержимого страницы, а порой двух, трёх, четырёх. Выявились у этого алгоритма огрехи, частично из-за проблем самой платформы с. Функция проверки возможности вывода ТабличныйДокумент.ПроверитьВывод(МассивДляПроверки) всегда возвращает клади Ложь если перед этим в ТабличныйДокумент не было выведено ни одной области. На массивах с большим количеством областей печати, код мог иногда выводить содержимое частично, оставляя 1/2 - 1/4 страницы не занятой, всё как обычно - ТабличныйДокумент.ПроверитьВывод(МассивДляПроверки) возвращала Ложь.
Было решено полностью переписать алгоритм функции, что только положительно сказалось на читаемости кода. избавился от рекурсии и выше перечисленных ошибок вывода.
Область колонтитула прижимается к низу страницы многократным выводом тоненькой пустой области печати, 1/5 стандартной высоты строки.
//Функция ВывестиНижнийКолонтитул, Изменит табличный документ, добавив нужное количество отступов,
//
//Возвращает - шаблон строки с колонтитулом, Данные записывать в Параметр - Содержание
//
//ТаблДокумент - табличный документ
//
//Параметры - Параметры с настройками вывода
//
//ПоследняяСтраница - Признак последней страницы
//
//При ошибочных параметрах функция завершится, не выполнив воегопредназночения, но вернёт макет "СтрокаКолонтитул", возможно даже обидится на пользователя или программиста
Функция ВывестиНижнийКолонтитул(ТабличныйДокумент, НижнийКолонтитул, Параметры, ПоследняяСтраница = Ложь) Экспорт
Если Не АНужноЛиВыводитьНКЛ(Параметры, НижнийКолонтитул, ПоследняяСтраница) Тогда
//Ну неД, так НЕД!
Возврат Ложь;
КонецЕсли;
//Больше кода, быстрее Вывод
//Строки большой высоты
ОбластьЧистаяСтрока = Параметры.СтрокаОтступВысокая;
//до конца страницы проверяем, чтоб сместить колонтитул вниз
ПроверитьМакетыНаВозможностьВывода = Новый Массив();
ПроверитьМакетыНаВозможностьВывода.Добавить(НижнийКолонтитул);
ПроверитьМакетыНаВозможностьВывода.Добавить(ОбластьЧистаяСтрока);
//Прижимаем НК в подвал страницы страницы
Пока ТабличныйДокумент.ПроверитьВывод(ПроверитьМакетыНаВозможностьВывода) Цикл
ТабличныйДокумент.Вывести(ОбластьЧистаяСтрока);
КонецЦикла;
//Строки средней высоты
ОбластьЧистаяСтрока = Параметры.СтрокаОтступСтандартная;
//до конца страницы проверяем, чтоб сместить колонтитул вниз
ПроверитьМакетыНаВозможностьВывода = Новый Массив();
ПроверитьМакетыНаВозможностьВывода.Добавить(НижнийКолонтитул);
ПроверитьМакетыНаВозможностьВывода.Добавить(ОбластьЧистаяСтрока);
//Прижимаем НК в подвал страницы страницы
Пока ТабличныйДокумент.ПроверитьВывод(ПроверитьМакетыНаВозможностьВывода) Цикл
ТабличныйДокумент.Вывести(ОбластьЧистаяСтрока);
КонецЦикла;
//Тонкими строками
//Добавлять будем строчками высотой в 1/5 стандартной, для большей точности, но дольше и глупее :-(
//Весь колонтитул прижимаем вот этой строчкой
ОбластьЧистаяСтрока = Параметры.СтрокаОтступ;
//до конца страницы проверяем, чтоб сместить колонтитул вниз
ПроверитьМакетыНаВозможностьВывода = Новый Массив();
ПроверитьМакетыНаВозможностьВывода.Добавить(НижнийКолонтитул);
ПроверитьМакетыНаВозможностьВывода.Добавить(ОбластьЧистаяСтрока);
//Прижимаем НК в подвал страницы страницы
Пока ТабличныйДокумент.ПроверитьВывод(ПроверитьМакетыНаВозможностьВывода) Цикл
ТабличныйДокумент.Вывести(ОбластьЧистаяСтрока);
КонецЦикла;
//И на закуску
ТабличныйДокумент.Вывести(НижнийКолонтитул);
//С разрывом тоже нужно , что - то решать.
Если ТипЗнч(Параметры.РазрывСтраниц) = Тип("Булево") и Параметры.РазрывСтраниц Тогда
ТабличныйДокумент.ВывестиГоризонтальныйРазделительСтраниц();
КонецЕсли;
Возврат Истина;
КонецФункции
Вывод ускоряем строками разной высоты, на примере они раскрашены разными цветами.
Пример использования вывода:
ОблНаПечать = Новый Массив;
ОблНаПечать.Добавить(Макет.ПолучитьОбласть("ЛоготипНаименование"));
ОблНаПечать.Добавить(Макет.ПолучитьОбласть("ШапкаДоговора"));
ОблНаПечать.Добавить(Макет.ПолучитьОбласть("ОбластьП1"));
ОблНаПечать.Добавить(Макет.ПолучитьОбласть("ОбластьП2_1_1"));
ОблНаПечать.Добавить(Макет.ПолучитьОбласть("ОбластьП2_3"));
ОблНаПечать.Добавить(Макет.ПолучитьОбласть("ОбластьП3_1"));
ОблНаПечать.Добавить(Макет.ПолучитьОбласть("ОбластьП3_2"));
ОблНаПечать.Добавить(Макет.ПолучитьОбласть("ОбластьП4_1"));
ОблНаПечать.Добавить(Макет.ПолучитьОбласть("ОбластьП6_2"));
ОблНаПечать.Добавить(Макет.ПолучитьОбласть("ОбластьРеквизиты"));
МакетВК = Макет.ПолучитьОбласть("ВерхнийКолонтитул"); // Можно и не передавать, код пережуёт это
МакетНК = Макет.ПолучитьОбласть("НижнийКолонтитул"); // Можно и не передавать, код пережуёт это
Макет1Строки = Макет.ПолучитьОбласть("ПустаяСтрока0001Высоты"); // Должна присутствовать в вашем макете
//Нужно если вы переностите код в общие модули, и используете для отступа области из общего макета.
ПараметрыВывода = ПолучитьСписокПараметров_МК();
ПараметрыВывода.СчитатьВсегоСтраниц = СчетСтраниц;
ПараметрыВывода.ВК_На_Первой = ВК_На_ПервойСтранице;
ПараметрыВывода.ВК_На_Последней = ВК_На_ПоследнейСтранице;
ПараметрыВывода.НК_На_Первой = НК_На_ПервойСтранице;
ПараметрыВывода.НК_На_Последней = НК_На_ПоследнейСтранице;
ПараметрыВывода.РазрывСтраниц = РазрывСтраниц;
ПараметрыВывода.ОднаСтраница = ОднаСтраница; // вывод одной страницы, функция вернёт массив не выведенных областей
ПараметрыВывода.Макет1Строки = Макет1Строки;
//Доступные параметры
// РазрывСтраниц = Истина
// ОднаСтраница = Ложь
// ВК_На_Первой = Истина //ВК - Верхний колонтитул
// ВК_На_Последней = Ложь
// НК_На_Первой = Истина //НК - Нижний колонтитул
// НК_На_Последней = Ложь
// СчитатьВсегоСтраниц = Ложь - Ускоряем вывод . но теряем реальное количество страниц. можно задать параметром ниже если знаем, что больше этого параметра их не будет.
// ТекущаяСтраница = 0
// ВсегоСтраниц = 0
// ФорматДаты = "ДЛФ=D"
// ФорматВремени = "ДЛФ=T"
ОблНаПечать = ВывестиМаксимумКонтента(ТабличныйДокумент, ОблНаПечать, МакетВК, МакетНК, ПараметрыВывода);
//Выведем всё что отсталось, Если ОднаСтраница = Истина
Для Каждого ТБ из ОблНаПечать Цикл
//Если не выводить то видим. что вывелось содержимого только до конца страницы
//ТабличныйДокумент.Вывести(ТБ);
КонецЦикла;
Плюсы моего решения:
- Выводит в колонтитулы абсолютно любую область с любым содержанием.
- Запрет вывода колонтитула на первой и последней странице. Актуально для договоров, когда на каждой странице кроме последней выводишь подписи сторон.
- Прижимание области колонтитула к низу страницы.
Минусы:
Пока отсутствует вывод верхнего колонтитула (не актуально, решаемо).Отсутствуют параметры с указанием номера текущей страницы (решается двойным формированием, либо вывод в цикле способом #1).- После изменения размеров верхнего и нижнего отступов необходимо заново формировать печатную форму.
- Ощутимо медленно работает, хотя не критично.
- 21.02.2018 Авто масштаб по ширине и широкая форма рушат всю логику. 1с делает вывод с учётом высоты страницы, а уже после поджимает результат по ширине.
Хотя минусов и больше, но возможности плюсов перевешивают их, и сейчас я использую этот код во многих печатных формах. Считаю, что и тебе он поможет в реализации своих идей с красивым выводом контента.
П.С. Тестировалось на платформе: 8.3.9.2170.
В обработке бонусом идёт функция проверки существования макета печатной формы, схожий в действии с функцией - ОбщегоНазначения.ЕстьРеквизитДокумента(), только ищет макет. Легко модернизируется на получение самого макета.
П.П.С. Обращение к разработчикам 1С. Добавьте к своему функционал печати возможность указать как начальную, так и конечную страницу вывода колонтитула, + возможность указанием в качестве шаблона произвольной области макета.
П.П.П.С Внесены доработки для работы кода в глобальном модуле. с.м. процедуру печати