При разработке печатных форм этикеток, ценников или штрихкодов в системе 1С:Предприятие программисты часто сталкиваются с нестандартным поведением размеров строк и колонок. Пытаясь задать точные физические размеры макета в миллиметрах, разработчики обнаруживают в типовом коде странные коэффициенты: например, умножение высоты на 2.65 вместо математически верного 2.83, или умножение ширины на 0.53. В этой статье мы подробно разберем природу этих коэффициентов, выясним причины их появления и рассмотрим лучшие практики точной верстки печатных форм под принтеры этикеток.
Чтобы понять, откуда берутся эти цифры, проанализируем внутреннее устройство табличного документа 1С. Платформа использует две разные системы измерения для вертикальных и горизонтальных элементов:
Разберем детально каждую из этих величин и сопоставим их с привычной метрической системой (миллиметрами).
Выясним причину расхождения теоретического коэффициента пересчета высоты строки и практического, используемого в типовых конфигурациях 1С.
Для начала обратимся к точным математическим формулам. Физический пункт (point) в компьютерной верстке жестко привязан к дюйму:
Если нам нужно перевести миллиметры в пункты, мы должны разделить исходное значение на 0.3528, что эквивалентно умножению на обратную величину:
1 / 0.3528 ≈ 2.8346.
Таким образом, математически точный коэффициент перевода миллиметров в пункты равен 2.83. Однако в коде типовых обработок печати этикеток мы видим коэффициент 2.65. Почему так происходит?
Проанализируем ситуацию на практике. Принтеры этикеток (термо- и термотрансферные принтеры) работают рулонным методом и крайне чувствительны к выходу за пределы физической области печати. Если высота сформированного табличного документа превысит физическую высоту этикетки хотя бы на 0.1 мм, драйвер принтера автоматически решит, что документ не поместился на одну этикетку, и прокрутит ленту вперед, выдав пустой лист в качестве «хвоста» печати.
Использование заниженного коэффициента 2.65 вместо 2.83 — это умышленный технологический запас (люфт порядка 6.5%). Данный коэффициент гарантирует, что высота сформированной области всегда окажется чуть меньше физической высоты бумажного носителя. Это надежно защищает от брака печати, компенсируя:
Теперь разберем ширину колонок табличного документа. В 1С ширина измеряется не в пунктах, а в условных «попугаях», которые привязаны к средней ширине символа базового системного шрифта платформы (обычно это MS Sans Serif или Times New Roman определенного кегля).
Экспериментальным и аналитическим путем разработчики вычислили точное соотношение этой условной единицы к миллиметрам:
Чтобы перевести миллиметры в единицы ширины колонки 1С, выполним деление:
1 мм / 1.8522 мм ≈ 0.5399 (то есть примерно 0.54).
Как и в случае с высотой, в реальном программном коде разработчики используют коэффициент 0.53. Это дает технологический запас около 2%, гарантируя, что правая граница штрихкода или цены не «съедет» за край узкой этикеточной ленты (например, при печати на стандартных рулонах шириной 43 мм, 58 мм или 80 мм).
Важно помнить, что верстка табличного документа сильно завязана на параметры отображения операционной системы. Если формирование макета происходит на стороне клиента, то итоговый размер элементов в пикселях может зависеть от системных настроек DPI (масштабирование экрана 125%, 150% в Windows).
При генерации печатной формы на сервере платформа использует стандартное разрешение экрана (обычно 96 DPI). Если клиентская машина имеет нестандартные настройки масштаба, макет при печати «напрямую» из тонкого клиента может исказиться или поплыть. Использование защитных коэффициентов 2.65 и 0.53 частично сглаживает эти неприятные эффекты, оставляя «воздушные зазоры» по краям этикетки.
Рассмотрим, как выглядит классический типовой алгоритм программной настройки размеров областей макета этикетки с использованием наших коэффициентов:
// Предположим, у нас есть параметры ВысотаЭтикетки и ШиринаЭтикетки в миллиметрах
ВысотаЭтикетки = 40; // 40 мм
ШиринаЭтикетки = 58; // 58 мм
// Создаем табличный документ для печати
ТабДок = Новый ТабличныйДокумент;
ТабДок.ИмяПараметровПечати = "ПараметрыПечати_Этикетка_58х40";
// Получаем области из макета
ОбластьНоменклатура = Макет.ПолучитьОбласть("Номенклатура");
ОбластьШтрихкод = Макет.ПолучитьОбласть("Штрихкод");
ОбластьЦена = Макет.ПолучитьОбласть("Цена");
// Задаем высоту строк в пунктах с коэффициентом 2.65
// Распределяем высоту этикетки: 30% под название, 50% под штрихкод, 20% под цену
ОбластьНоменклатура.ВысотаСтроки = ВысотаЭтикетки * 2.65 * 0.3;
ОбластьШтрихкод.ВысотаСтроки = ВысотаЭтикетки * 2.65 * 0.5;
ОбластьЦена.ВысотаСтроки = ВысотаЭтикетки * 2.65 * 0.2;
// Выводим области в итоговый документ
ТабДок.Вывести(ОбластьНоменклатура);
ТабДок.Вывести(ОбластьШтрихкод);
ТабДок.Вывести(ОбластьЦена);
// Устанавливаем ширину колонки всего документа с коэффициентом 0.53
ТабДок.Область(1, 1, ТабДок.ВысотаТаблицы, 1).ШиринаКолонки = ШиринаЭтикетки * 0.53;
Если сетка табличного документа накладывает слишком жесткие ограничения и не позволяет добиться идеального позиционирования элементов, опытные разработчики рекомендуют отказаться от изменения высоты строк и ширины колонок. Вместо этого проанализируем альтернативный вариант верстки — динамическое размещение графических объектов (рисунков) внутри макета.
Преимущество этого метода в том, что размеры объектов типа РисунокТабличногоДокумента можно задавать в миллиметрах напрямую через свойства Высота и Ширина, минуя любые условные единицы платформы.
Посмотрим на пример программной генерации этикетки с использованием рисунков:
ТабДок = Новый ТабличныйДокумент;
// Отключаем поля, чтобы печать шла строго от края области
ТабДок.ПолеСверху = 0;
ТабДок.ПолеСнижу = 0;
ТабДок.ПолеСлева = 0;
ТабДок.ПолеСправа = 0;
// Определяем область вывода рисунков
ОбластьДляРисунков = ТабДок.Область("R1C1:R10C10");
// Добавляем рисунок текста (номенклатура)
РисунокТекст = ТабДок.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Текст);
РисунокТекст.Расположить(ОбластьДляРисунков);
// Устанавливаем размеры напрямую в миллиметрах!
РисунокТекст.Ширина = 54; // Ширина в мм с учетом небольшого отступа
РисунокТекст.Высота = 12; // Высота в мм
РисунокТекст.Верх = 2;
РисунокТекст.Лево = 2;
РисунокТекст.Текст = "Товар: Конструктор детский ""Лего""";
РисунокТекст.Шрифт = Новый Шрифт("Arial", 10, Истина);
// Добавляем рисунок штрихкода
РисунокШтрихкод = ТабДок.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
РисунокШтрихкод.Расположить(ОбластьДляРисунков);
РисунокШтрихкод.Ширина = 54;
РисунокШтрихкод.Высота = 20;
РисунокШтрихкод.Верх = 15;
РисунокШтрихкод.Лево = 2;
РисунокШтрихкод.Картинка = ПолучитьКартинкуШтрихкода("4601234567890");
Используя этот подход, мы полностью избавляемся от необходимости подбирать коэффициенты для высоты ячеек и ширины колонок, так как платформа берет на себя точную физическую адресацию элементов при отправке задания на печать.
Если ваша конфигурация работает на современной платформе 1С:Предприятие 8.3 и перед вами стоит задача разработать действительно отказоустойчивую систему печати ценников, рассмотрите возможность рендеринга макетов в формат PDF. Платформа 1С позволяет сохранять сформированный табличный документ в PDF программно.
Формат PDF жестко фиксирует векторную разметку и все физические размеры до десятых долей миллиметра. При печати такого файла через драйвер принтера вероятность смещения или появления пустых этикеток сводится к нулю, независимо от установленного DPI экрана на компьютере пользователя.