При формировании сложных печатных форм в 1С разработчики часто сталкиваются с неприятной особенностью: если область макета (например, состоящая из 5–10 строк) не помещается на текущую страницу целиком, система переносит ее на следующий лист. В результате внизу предыдущей страницы остается внушительное пустое пространство, которое портит внешний вид документа и увеличивает расход бумаги. В этой статье мы подробно разберем, как заставить 1С заполнять страницу максимально плотно, выводя данные построчно.
Разберем причину такого поведения системы. Когда мы используем метод Вывести() для целой области, 1С воспринимает эту область как неделимый блок. Если в блоке несколько строк, и хотя бы одна из них выходит за границы печатной страницы, алгоритм переноса срабатывает для всей области целиком. Чтобы этого избежать, нам нужно изменить логику вывода так, чтобы система принимала решение о переносе для каждой строки в отдельности.
Наиболее эффективный способ, предложенный опытными разработчиками, заключается в том, чтобы не выводить всю область целиком, а перебрать ее строки в цикле и выводить их по одной. Таким образом, если на странице осталось место для двух строк из пяти, эти две строки будут напечатаны, а остальные три перенесутся на следующий лист.
Рассмотрим пример кода, который реализует этот подход. Предположим, у нас есть макет с областью БольшаяОбласть, которую нужно вывести построчно.
&НаСервере
Функция СформироватьТабличныйДокумент()
ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("Макет");
// Получаем исходную многострочную область
БольшаяОбласть = Макет.ПолучитьОбласть("БольшаяОбласть");
// Определяем параметры области
ШиринаОбласти = БольшаяОбласть.ШиринаТаблицы;
ВысотаОбласти = БольшаяОбласть.ВысотаТаблицы;
// Перебираем каждую строку области отдельно
Для СчСтрок = 1 По ВысотаОбласти Цикл
// Получаем область размером в одну строку
// Синтаксис: ПолучитьОбласть(Верх, Лево, Низ, Право)
МаленькаяОбласть = БольшаяОбласть.ПолучитьОбласть(СчСтрок, 1, СчСтрок, ШиринаОбласти);
// Выводим строку в итоговый документ
ТабДок.Вывести(МаленькаяОбласть);
КонецЦикла;
Возврат ТабДок;
КонецФункции
Проанализируем этот код: мы используем свойство ВысотаТаблицы, чтобы узнать, сколько строк содержится в исходной области. Затем с помощью метода ПолучитьОбласть() мы буквально "нарезаем" исходную область на тонкие полоски высотой в одну ячейку. При таком подходе 1С заполняет страницу до самого нижнего края.
Иногда нам важно не просто заполнить место, но и корректно обработать ситуацию, когда вместе со строкой должен выводиться какой-то дополнительный элемент (например, номер страницы или промежуточный итог). В этом случае мы можем использовать метод ПроверитьВывод(). Выясним, как это работает на практике.
Метод ПроверитьВывод() принимает массив областей и возвращает Истина, если они помещаются на текущую страницу с учетом текущих настроек принтера и полей. Рассмотрим алгоритм с проверкой:
Процедура ВывестиПострочноСКонтролем(ТабДок, ИсходнаяОбласть)
Для Сч = 1 По ИсходнаяОбласть.ВысотаТаблицы Цикл
СтрокаДляВывода = ИсходнаяОбласть.ПолучитьОбласть(Сч, 1, Сч, ИсходнаяОбласть.ШиринаТаблицы);
МассивОбластей = Новый Массив;
МассивОбластей.Добавить(СтрокаДляВывода);
Если Не ТабДок.ПроверитьВывод(МассивОбластей) Тогда
// Здесь можно вывести разделитель или подвал страницы
// ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
// ТабДок.Вывести(ОбластьПодвала);
КонецЕсли;
ТабДок.Вывести(СтрокаДляВывода);
КонецЦикла;
КонецПроцедуры
Важно понимать ограничение: если ваша область состоит всего из одной строки, но в одной из ее ячеек находится огромный текст с включенным свойством Размещать = Переносить, вышеописанные методы не помогут. В 1С одна строка табличного документа является минимальной неделимой единицей вывода. Если высота одной строки (из-за объема текста) превышает высоту печатного листа, 1С все равно перенесет ее целиком.
Как это решить?
Посмотрим на настройки самого ТабличногоДокумента, которые напрямую влияют на количество свободного места внизу страницы:
ПолеСнизу. По умолчанию там может стоять 10 мм. Уменьшение этого значения до 5 мм или даже 0 мм (если принтер позволяет) даст дополнительное место для нескольких строк.НижнийКолонтитул = 0, чтобы освободить пространство.ТабДок.Автомасштаб = Истина; позволяет системе немного уменьшить весь документ, чтобы "впихнуть" невместившиеся строки, минимизируя пустоту.ВместеССледующим, 1С будет принудительно переносить их группой, создавая те самые пустые места.Подведем итог нашему анализу. Чтобы избавиться от пустых мест внизу листа при печати в 1С, необходимо:
ПолучитьОбласть(НомерСтроки, 1, НомерСтроки, Ширина).ПроверитьВывод(), если требуется специфическое оформление переносов.Применяя эти методы, мы добьемся профессионального и компактного вида печатных форм, максимально эффективно используя площадь бумажного листа.