Разработка печатных форм в 1С — задача, с которой сталкивается каждый программист. Однако часто возникает неприятная ситуация: на компьютере разработчика макет выглядит идеально, страницы укладываются ровно в формат A4, но у конечных пользователей табличный документ начинает «плясать». Строки переносятся на новые листы, ломаются границы, появляются пустые страницы, а фиксированные области не попадают в размер листа.
В этой статье мы подробно разберем, почему макеты разъезжаются на разных рабочих станциях, и рассмотрим практические программные методы решения этой проблемы, включая управление параметрами печати, правильное использование масштабирования, принудительное разделение страниц и работу с пакетами документов.
--- ### Выясняем причину: почему макет «плывет» на разных ПК?
Прежде чем переходить к написанию кода, давайте проанализируем ситуацию и поймем физику процесса. Табличный документ 1С не является жестким PDF-файлом. Это динамический объект, визуализация которого сильно зависит от окружения операционной системы конкретного пользователя. Выделим три главные причины деформации:
--- ### Решение 1. Использование «Ключа параметров печати» и правильный порядок инициализации
Для того чтобы настройки печати (такие как масштаб, поля, ориентация) сохранялись индивидуально для каждого макета и не сбрасывались при каждом открытии, платформа предоставляет свойства КлючПараметровПечати (или ИмяПараметровПечати в зависимости от версии платформы и режима управляемых/обычных форм).
Важнейшее правило: параметры страницы по умолчанию (например, поля или свойство автомасшаба) необходимо задавать в коде ДО присвоения значения свойству КлючПараметровПечати. Рассмотрим пример:
ТабДок = Новый ТабличныйДокумент;
// 1. Сначала задаем дефолтные параметры страницы
ТабДок.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;
ТабДок.АвтоМасштаб = Истина;
ТабДок.ПолеСверху = 10;
ТабДок.ПолеСнизу = 10;
ТабДок.ПолеСлева = 10;
ТабДок.ПолеСправа = 10;
// 2. Только теперь задаем ключ параметров печати!
ТабДок.КлючПараметровПечати = "УникальныйКлючМоегоМаккета_РТиУ";
Почему это важно? Когда мы присваиваем свойство КлючПараметровПечати, платформа 1С мгновенно обращается к системному хранилищу настроек пользователя и пытается загрузить оттуда параметры, которые он выставил вручную при прошлой печати этого документа. Если мы сначала укажем ключ, а потом принудительно пропишем в коде ТабДок.АвтоМасштаб = Истина;, мы грубо перетрем пользовательские индивидуальные настройки. Если же соблюдать указанный выше порядок, то программные установки сработают только как значения «по умолчанию» (при первом запуске), а последующие ручные корректировки пользователя корректно сохранятся и не будут перезаписываться кодом.
--- ### Решение 2. Программный контроль вывода областей на страницу
Если макет содержит строго две страницы (например, титульный лист и основная спецификация), и нам критически важно, чтобы первая область выводилась на первой странице, а вторая — строго на второй, мы можем принудительно управлять разбивкой страниц.
Рассмотрим подробнее, как объединить две статические области в один документ с жестким разделителем:
ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("МойМакет");
// Получаем области для первой и второй страниц
ОбластьСтраница1 = Макет.ПолучитьОбласть("Страница1");
ОбластьСтраница2 = Макет.ПолучитьОбласть("Страница2");
// Выводим первую страницу
ТабДок.Вывести(ОбластьСтраница1);
// Принудительно вставляем горизонтальный разделитель страниц
ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
// Выводим вторую страницу
ТабДок.Вывести(ОбластьСтраница2);
Важный нюанс: Метод СоздатьФорматСтрок(). Если ширина колонок на первой и второй страницах вашего макета различается, при их выводе в один табличный документ сетка неизбежно деформируется (одна страница подстроится под ширину колонок другой). Чтобы избежать «разъезжания» колонок, используйте метод СоздатьФорматСтрок() после вывода каждой логической страницы:
ТабДок = Новый ТабличныйДокумент;
// Выводим первую область
ТабДок.Вывести(ОбластьСтраница1);
// Фиксируем колонки для выведенных строк
ТабДок.СоздатьФорматСтрок();
// Разделяем страницы
ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
// Выводим вторую область
ТабДок.Вывести(ОбластьСтраница2);
// Фиксируем колонки для второй части документа
ТабДок.СоздатьФорматСтрок();
--- ### Решение 3. Динамический подбор масштаба через ПроверитьВывод()
Что делать, если на некоторых принтерах страница всё равно не помещается по высоте и переносится на следующий лист? Мы можем заставить систему программно проверять, помещается ли сформированная область на лист при текущих настройках принтера, и динамически уменьшать масштаб печати, если область выходит за границы страницы.
Проанализируем пример функции динамического масштабирования:
// Создаем массив областей для проверки
МассивОбластей = Новый Массив;
МассивОбластей.Добавить(ОбластьСтраница1);
// Задаем начальный масштаб
ТабДок.МасштабПечати = 100;
// Если область не влезает на одну страницу при масштабе 100%,
// начинаем плавно уменьшать масштаб в цикле
Пока Не ТабДок.ПроверитьВывод(МассивОбластей) И ТабДок.МасштабПечати > 80 Цикл
ТабДок.МасштабПечати = ТабДок.МасштабПечати - 2; // Уменьшаем масштаб на 2%
КонецЦикла;
// Теперь выводим область с гарантией, что она поместится
ТабДок.Вывести(ОбластьСтраница1);
Этот метод опирается на реальные метрики принтера по умолчанию, установленного у пользователя. Мы заставляем платформу «примерить» документ к листу перед выводом на экран и гибко уменьшить масштаб только на тех компьютерах, где это действительно необходимо.
--- ### Решение 4. Использование ПакетОтображаемыхДокументов
Если наши страницы настолько разные, что их невозможно корректно объединить в рамках одного табличного документа (например, первая страница должна быть портретной ориентации, а вторая — ландшафтной, либо у них кардинально различаются настройки полей), на помощь приходит объект ПакетОтображаемыхДокументов.
Этот механизм позволяет сформировать несколько независимых табличных документов и объединить их в единый пакет печати. Для пользователя это будет выглядеть как один документ: при отправке на печать сформируется одно задание в очереди принтера, а при сохранении в формат PDF получится один многостраничный файл.
Разберем программную реализацию этой схемы:
// 1. Создаем и заполняем первую страницу
ТабДок1 = Новый ТабличныйДокумент;
ТабДок1.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;
ТабДок1.Вывести(ОбластьСтраница1);
// 2. Создаем и заполняем вторую страницу
ТабДок2 = Новый ТабличныйДокумент;
ТабДок2.ОриентацияСтраницы = ОриентацияСтраницы.Ландшафт;
ТабДок2.Вывести(ОбластьСтраница2);
// 3. Создаем пакет документов
Пакет = Новый ПакетОтображаемыхДокументов;
// Помещаем первый документ во временное хранилище и добавляем в пакет
Адрес1 = ПоместитьВоВременноеХранилище(ТабДок1);
ЭлементПакета1 = Пакет.Состав.Добавить();
ЭлементПакета1.Данные = Адрес1;
// Помещаем второй документ во временное хранилище и добавляем в пакет
Адрес2 = ПоместитьВоВременноеХранилище(ТабДок2);
ЭлементПакета2 = Пакет.Состав.Добавить();
ЭлементПакета2.Данные = Адрес2;
// Отображаем пакет пользователю или сразу отправляем на печать
Пакет.Показать("Печать пакета документов");
--- ### Общие рекомендации по проектированию стабильных макетов
Для того чтобы свести к минимуму вероятность «расползания» областей, придерживайтесь следующих правил при разработке макетов в Конфигураторе:
Arial, Times New Roman, Courier New, Verdana. Избегайте использования экзотических или узкоспециализированных шрифтов.Применяя предложенные методы в комплексе — правильную инициализацию параметров страницы, динамический контроль через ПроверитьВывод() и разделение форматов строк, вы добьетесь стабильного и прогнозируемого поведения ваших печатных форм на любом компьютере вашей компании.