Разработка и печать этикеток во внешних обработках и документах 1С — задача, с которой регулярно сталкивается любой программист. Очень часто при попытке настроить жесткие нестандартные размеры страницы, например, популярный формат 90х60 мм или 58х40 мм, разработчик сталкивается с неожиданным поведением системы: вместо одной аккуратной этикетки принтер выдает четыре страницы (сетку 2х2), на каждой из которых распечатывается лишь часть макета или вовсе пустые поля.
В этой статье мы подробно разберем, почему возникает этот эффект, проанализируем внутренние механизмы платформы 1С:Предприятие, управляющие выводом табличных документов, и рассмотрим несколько профессиональных способов решения этой проблемы.
Когда мы программно отключаем автоматическое масштабирование и задаем фиксированные размеры страницы, платформа рассчитывает размеры выводимых областей с точностью до десятых долей миллиметра. Проанализируем типичный код инициализации параметров печати:
ТабличныйДокумент = Новый ТабличныйДокумент;
ТабличныйДокумент.ПолеСверху = 0;
ТабличныйДокумент.ПолеСлева = 0;
ТабличныйДокумент.ПолеСнизу = 0;
ТабличныйДокумент.ПолеСправа = 0;
ТабличныйДокумент.Автомасштаб = Ложь;
ТабличныйДокумент.РазмерСтраницы = "Custom";
ТабличныйДокумент.ШиринаСтраницы = 90;
ТабличныйДокумент.ВысотаСтраницы = 60;
Если при таких настройках физический размер области макета (включая ширину колонок, высоту строк, толщину линий и невидимые границы ячеек) хотя бы на 0.1 мм превысит установленные 90 мм по ширине или 60 мм по высоте, система поведет себя следующим образом:
Рассмотрим детально 5 основных способов решения этой проблемы, начиная от простых манипуляций с макетом и заканчивая системными настройками драйверов печати.
Самый очевидный и быстрый способ, к которому пришел автор темы, — это физическое уменьшение границ макета в конфигураторе 1С. Когда мы рисуем макет, мы ориентируемся на визуальные границы. Но реальные размеры ячеек в свойствах строк и колонок могут быть чуть больше расчетных.
Рекомендуется выполнить следующие действия в конфигураторе:
// Вместо точных 90х60 задаем небольшой запас, если это позволяет лента принтера
ТабличныйДокумент.ШиринаСтраницы = 95;
ТабличныйДокумент.ВысотаСтраницы = 65;
Это позволит макету гарантированно «вписаться» в один лист без активации механизмов переноса на соседние страницы.
Для того чтобы не подбирать размеры ячеек вручную «на глаз», в платформе 1С предусмотрено встроенное свойство автоматического масштабирования табличного документа. Оно заставляет систему пропорционально сжимать выводимый макет до тех пор, пока он полностью не уместится на одну страницу.
Для активации этого режима достаточно изменить всего одну строку в коде формирования этикетки:
// Включаем автоматическое масштабирование макета под размер страницы
ТабличныйДокумент.Автомасштаб = Истина;
При включенном свойстве Автомасштаб платформа сама уменьшит шрифты, картинки и отступы макета так, чтобы они уместились строго на одном физическом листе бумаги заданного формата, предотвращая появление лишних страниц.
Дополнительно перед выводом документа на печать мы можем программно проверить, помещается ли наш макет на страницу, с помощью метода ПроверитьВывод():
МассивОбластей = Новый Массив;
МассивОбластей.Добавить(Шапка);
Если Не ТабличныйДокумент.ПроверитьВывод(МассивОбластей) Тогда
ЗаписьЖурналаРегистрации("Печать", УровеньЖурналаРегистрации.Предупреждение, , , "Макет этикетки не помещается на одну страницу!");
КонецЕсли;
Платформа 1С кэширует настройки печати (поля, ориентацию, масштаб, принтер) для каждого пользователя. Настройки привязываются к имени формы или специальному свойству КлючПараметровПечати (или ИмяПараметровПечати).
Если вы не укажете этот ключ, система может применить к вашей маленькой этикетке ранее сохраненные настройки печати обычного документа (например, формата А4 с широкими полями). Это приведет к хаосу при расчете масштаба.
Обязательно задавайте уникальный строковый ключ для вашей этикетки:
// Установка уникального ключа параметров печати для сохранения индивидуальных настроек
ТабличныйДокумент.КлючПараметровПечати = "ПараметрыПечати_Этикетка_90х60";
Благодаря этому драйвер принтера и 1С запомнят настройки (включая тип бумаги и поля) именно для этого макета, и при повторном открытии формы печать будет работать стабильно.
Программное свойство РазмерСтраницы = "Custom" передает операционной системе Windows абстрактную команду на печать нестандартного размера. Далеко не все драйверы принтеров (особенно сетевые или работающие в терминальных сессиях RDP) корректно обрабатывают этот параметр. Часто драйвер сбрасывает настройки на формат по умолчанию (Letter или А4).
Более надежный и профессиональный подход заключается в предварительной подготовке операционной системы:
Label_90x60) и задайте точные размеры: ширина 9.00 см, высота 6.00 см. Сохраните формат.Label_90x60 по умолчанию.
// Указываем конкретный именованный формат, зарегистрированный в Windows
ТабличныйДокумент.РазмерСтраницы = "Label_90x60";
Драйвер принтера мгновенно распознает именованный формат, что исключит любые искажения масштаба и произвольные разбиения страниц.
Автор темы упоминает важный нюанс: тестирование макета производится на обычном офисном принтере формата А4 за отсутствием специализированного принтера этикеток.
Обычные офисные лазерные и струйные принтеры имеют аппаратные непечатные поля (обычно от 4 до 6 мм по краям листа). Принтер физически не может наносить тонер в этих зонах из-за особенностей механизмов протяжки бумаги.
Если мы программно задаем нулевые поля:
ТабличныйДокумент.ПолеСлева = 0;
ТабличныйДокумент.ПолеСправа = 0;
то драйвер стандартного офисного принтера принудительно сдвинет или сожмет макет, чтобы учесть свои технологические ограничения. Этот сдвиг приводит к выходу макета за границы виртуальной страницы и, как результат, к делению на 4 листа.
Решение при тестировании на офисном принтере: Задайте минимальные технологические поля в коде (например, по 5 мм с каждой стороны) и соответствующим образом уменьшите область самого макета, либо тестируйте печать только на специализированных термопринтерах (Zebra, TSC, Godex), которые поддерживают печать "в край" (без полей).
Проанализируем и соберем воедино все рекомендации. Ниже представлен корректный, отказоустойчивый шаблон функции печати этикетки с использованием всех защитных механизмов платформы 1С:
Функция ПечатьДокумента(МассивОбъектов, ОбъектыПечати, СПечатью = Ложь) Экспорт
Ссылка = МассивОбъектов[0];
УстановитьПривилегированныйРежим(Истина);
ТабличныйДокумент = Новый ТабличныйДокумент;
// Задаем минимальные поля для предотвращения конфликтов с драйверами
ТабличныйДокумент.ПолеСверху = 1;
ТабличныйДокумент.ПолеСлева = 1;
ТабличныйДокумент.ПолеСнизу = 1;
ТабличныйДокумент.ПолеСправа = 1;
ТабличныйДокумент.РазмерКолонтитулаСверху = 0;
ТабличныйДокумент.РазмерКолонтитулаСнизу = 0;
// Включаем автокоррекцию масштаба
ТабличныйДокумент.Автомасштаб = Истина;
// Явно указываем 1 экземпляр на странице
ТабличныйДокумент.ЭкземпляровНаСтранице = 1;
// Настройка уникальных параметров печати
ТабличныйДокумент.КлючПараметровПечати = "ПараметрыПечати_Этикетка_90х60";
// Пытаемся применить именованный системный формат или задаем Custom с запасом
ТабличныйДокумент.РазмерСтраницы = "Custom";
ТабличныйДокумент.ШиринаСтраницы = 90;
ТабличныйДокумент.ВысотаСтраницы = 60;
// Получение данных и заполнение макета
Макет = ПолучитьМакет("ИмяМакета");
Шапка = Макет.ПолучитьОбласть("Шапка");
// [Здесь выполняется заполнение параметров области Шапка]
ТабличныйДокумент.Вывести(Шапка);
Возврат ТабличныйДокумент;
КонецФункции
Использование этого шаблона гарантирует, что ваша этикетка всегда будет выводиться ровно в одном экземпляре на одну страницу, независимо от того, на каком принтере и в каком окружении (локально или через RDP) выполняется печать.