При работе с платформой 1С:Предприятие 8.3 программисты часто сталкиваются с задачей формирования и вывода на печать сложных табличных документов. Одним из ключевых моментов является корректное размещение информации на страницах, контроль разрывов и обеспечение оптимального масштаба печати. В этой статье мы подробно разберем, как эффективно управлять этими процессами, чтобы ваш табличный документ, состоящий из множества областей, выглядел на печати именно так, как вы задумали.
Представим ситуацию, когда табличный документ, который должен занимать две страницы, разворачивается на пятнадцать. Это может произойти из-за некорректного управления разрывами страниц или неверных настроек масштабирования. Мы выясним, как решить эту проблему, используя доступные средства 1С.
Один из самых прямых способов контроля размещения информации на страницах — это принудительная вставка горизонтального разделителя страниц. Метод ТабДок.ВывестиГоризонтальныйРазделительСтраниц(); позволяет точно определить, в каком месте документ перейдет на новую страницу. Этот подход особенно полезен, когда у вас есть четкое представление о структуре документа и о том, какие блоки должны находиться на одной странице, а какие — на следующей.
Рассмотрим пример, когда документ состоит из нескольких логических частей, которые необходимо распределить по страницам. Допустим, у нас есть макет, разбитый на именованные области, и мы хотим вывести определенное количество этих областей на первую страницу, а остальные — на вторую и последующие.
Процедура ВывестиДанныеВТабличныйДокументПоОбъектуЧастями(Макет, ПараметрыМакета, ДокументРезультат, ВсегоЧастей)
Для НомерЧасти = 0 По ВсегоЧастей - 1 Цикл // Перебираем части от 0 до ВсегоЧастей - 1
ЧастьИмя = "Часть" + Формат(НомерЧасти,"ЧН=; ЧГ="); // Имя области в макете, например "Часть0", "Часть1"
Попытка
ОбластьЧасть = Макет.ПолучитьОбласть(ЧастьИмя);
Исключение
СообщениеТекст = "При печати: " + ДокументРезультат.КлючПараметровПечати + " не удалось получить часть № " + НомерЧасти + ". Обратитесь к разработчику!";
Сообщить(СообщениеТекст);
Возврат;
КонецПопытки;
ОбластьЧасть.Параметры.Заполнить(ПараметрыМакета);
ДокументРезультат.Вывести(ОбластьЧасть);
// Вставляем разделитель страниц после определенных частей
Если НомерЧасти + 1 = 5 Тогда
ДокументРезультат.ВывестиГоризонтальныйРазделительСтраниц(); // Первые 5 частей на первый лист.
ИначеЕсли НомерЧасти + 1 = 8 Тогда
ДокументРезультат.ВывестиГоризонтальныйРазделительСтраниц(); // 6, 7, 8 на второй лист.
ИначеЕсли НомерЧасти + 1 = 10 Тогда
ДокументРезультат.ВывестиГоризонтальныйРазделительСтраниц(); // 9, 10 на третий лист.
КонецЕсли;
КонецЦикла;
КонецПроцедуры
В этом примере мы видим, что разделитель страниц вставляется после вывода 5-й, 8-й и 10-й части. Такой подход позволяет нам точно контролировать, какие блоки данных попадут на каждый лист. Если ваши области называются не "Часть0", "Часть1" и т.д., а имеют осмысленные имена типа "Шапка", "ОсновнаяЧасть", "Подвал", то логика остается той же. Вы просто выводите каждую область по очереди и вставляете разделитель, когда считаете нужным перейти на новую страницу, например, после вывода "Шапки" и нескольких "СтрокТабличнойЧасти", но до вывода "Итогов".
Например, если у вас есть области с именами ШапкаДокумента, СтрокаТабличнойЧасти и ПодвалДокумента, вы можете построить логику следующим образом:
// ... код вывода ШапкаДокумента
ТабДок.Вывести(Макет.ПолучитьОбласть("ШапкаДокумента"));
// ... цикл вывода СтрокаТабличнойЧасти
Для КаждаяСтрока Из Данные.Строки Цикл
// Проверка, помещается ли текущая строка на лист
// Если нет, вставляем разделитель
Если НЕ ТабДок.ПроверитьВывод(Макет.ПолучитьОбласть("СтрокаТабличнойЧасти")) Тогда
ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
КонецЕсли;
ТабДок.Вывести(Макет.ПолучитьОбласть("СтрокаТабличнойЧасти"));
КонецЦикла;
// Вставляем разделитель, если ПодвалДокумента не помещается вместе с последней строкой
Если НЕ ТабДок.ПроверитьВывод(Макет.ПолучитьОбласть("ПодвалДокумента")) Тогда
ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
КонецЕсли;
ТабДок.Вывести(Макет.ПолучитьОбласть("ПодвалДокумента"));
Этот пример демонстрирует сочетание принудительного разделителя с динамической проверкой, что подводит нас к следующему важному методу.
ПроверитьВыводВ типовых конфигурациях 1С, таких как Зарплата и Управление Персоналом (ЗКГУ) или ERP, часто используются вспомогательные функции для динамической проверки размещения областей. Такая функция, как ОбщегоНазначения.ПроверитьВыводТабличногоДокумента(), позволяет заранее узнать, поместится ли одна или несколько областей на текущей странице, с учетом выбранного принтера и его параметров печати.
Метод ТабличныйДокумент.ПроверитьВывод(<Таблицы>); возвращает Истина, если указанные области поместятся без создания новой страницы, и Ложь в противном случае. Если метод возвращает Ложь, при следующем выводе будет автоматически создана новая страница. Параметром может быть как отдельная область, так и массив областей.
Эта функция чрезвычайно полезна, когда мы хотим избежать ситуации, при которой, например, "подвал" документа или логически связанная группа строк окажется на отдельной, пустой странице. Мы можем использовать ее для более интеллектуального управления разрывами страниц.
Рассмотрим, как это можно применить на практике:
// Создаем массив областей, которые хотим вывести
МассивВыводимыхОбластей = Новый Массив;
МассивВыводимыхОбластей.Добавить(Макет.ПолучитьОбласть("ПодвалДокумента"));
МассивВыводимыхОбластей.Добавить(Макет.ПолучитьОбласть("ИтоговаяСтрока"));
// Проверяем, поместятся ли эти области на текущей странице
Если НЕ ОбщегоНазначения.ПроверитьВыводТабличногоДокумента(ТабличныйДокумент, МассивВыводимыхОбластей) Тогда
// Если не помещаются, принудительно вставляем разделитель
ТабличныйДокумент.ВывестиГоризонтальныйРазделительСтраниц();
КонецЕсли;
// Теперь выводим области, они точно будут вместе либо на текущей, либо на новой странице
ТабличныйДокумент.Вывести(Макет.ПолучитьОбласть("ПодвалДокумента"));
ТабличныйДокумент.Вывести(Макет.ПолучитьОбласть("ИтоговаяСтрока"));
В этом примере функция ПроверитьВыводТабличногоДокумента (или ее аналог в вашей конфигурации, как ТабличныйДокумент.ПроверитьВывод()) позволяет нам предвидеть проблему и избежать "висячих" элементов. Подобные функции обычно находятся в общих модулях, отвечающих за работу с печатными формами или общие утилиты, например, ОбщегоНазначения или УправлениеПечатью.
Другой полезный метод - ТабличныйДокумент.ПроверитьПрисоединение(). Он проверяет, уместится ли текст на лист по горизонтали при использовании метода Присоединить(). Это актуально, когда вы динамически формируете текст, который может выходить за пределы страницы.
Одной из частых проблем является то, что табличный документ не помещается по ширине на страницу, или наоборот, занимает слишком мало места. Свойство ТабДок.Автомасштаб = Истина; предназначено для автоматического подбора масштаба документа по ширине страницы. Однако, как показывает практика, это свойство не всегда работает ожидаемым образом или может быть переопределено другими механизмами печати конфигурации. Вы можете установить его, но результат может быть неочевиден.
Если Автомасштаб не срабатывает, или вы хотите более тонко настроить масштабирование, мы рекомендуем задавать конкретный масштаб печати в процентах через свойство МасштабПечати. Это дает вам полный контроль над тем, насколько документ будет уменьшен или увеличен при печати.
// После формирования всего табличного документа
ТабДок.Автомасштаб = Истина; // Попытаемся использовать автомасштаб
// Если автомасштаб не дает желаемого результата или нужна более точная настройка:
// ТабДок.МасштабПечати = 60; // Устанавливаем масштаб в 60% от исходного размера
Важно отметить, что установка Автомасштаб = Истина; должна производиться после того, как все области документа были выведены. Иногда типовые механизмы печати в конфигурациях могут сбрасывать или игнорировать это свойство, если оно установлено слишком рано. Если вам нужен гарантированный масштаб, лучше использовать МасштабПечати.
Помимо горизонтального масштаба, часто возникает потребность в управлении высотой строк. Свойства ВысотаСтроки и АвтоВысотаСтроки для табличных полей позволяют гибко настраивать вертикальное размещение текста:
АвтоВысотаСтроки = Истина, высота строки будет автоматически подбираться в зависимости от содержимого текста. Это удобно для динамического текста, который может занимать разное количество строк.ВысотаСтроки имеет значение, отличное от 0, АвтоВысотаСтроки становится Ложь, и высота строки фиксируется. Это полезно для создания строго структурированных форм.ВысотаСтроки как максимальную высоту, при этом АвтоВысотаСтроки останется Истина. В этом случае высота строки будет переменной, но не превысит заданного значения. Это позволяет тексту занимать столько места, сколько нужно, но не выходить за определенные рамки, предотвращая чрезмерно высокие строки.Для создания профессионально выглядящих печатных форм в 1С мы можем использовать еще несколько полезных свойств и методов:
ВместеСоСледующим: Для строк макета можно установить это свойство. Если оно установлено для первой строки в группе, то эта строка будет печататься вместе со следующими строками. Это предотвращает разрыв логически связанных данных (например, заголовка раздела и первой строки этого раздела) между страницами.ПовторятьПриПечатиСтроки и ПовторятьПриПечатиКолонки. Например:
ТабДок.ПовторятьПриПечатиСтроки = ТабДок.Область(5, , 10); // Будут выводиться строки с 5-й по 10-ю на каждой странице.
ОбластьПечати табличного документа определяет, какая часть документа будет выводиться на принтер. Например, если вам нужно напечатать только конкретный диапазон строк:
ТабДок.ОбластьПечати = ТабДок.Область(5, , 10); // Заставит печатать только строки с 5-й по 10-ю.
При работе с печатью табличных документов необходимо учитывать несколько важных моментов, которые помогут избежать распространенных ошибок:
Освоив эти методы и рекомендации, вы сможете создавать сложные и управляемые печатные формы в 1С, которые точно соответствуют вашим требованиям по размещению информации и масштабированию.