При разработке макетов для печати этикеток на листах формата А4 программисты часто сталкиваются с неприятной особенностью платформы 1С:Предприятие. Несмотря на возможность указать в свойствах ячейки дробные значения (например, 72.80), система часто «откатывает» их к ближайшим дискретным величинам (например, 72.75). На одной этикетке погрешность в 0.05 мм или 0.05 пункта незаметна, но при печати 10–40 рядов на одном листе ошибка накапливается, и последние ряды «съезжают» с разметки. Рассмотрим причины этой проблемы и разберем все способы её решения.
Проанализируем ситуацию с технической стороны. Внутренняя архитектура табличного документа 1С использует для расчетов не метрическую систему, а специфические единицы измерения. Высота строк измеряется в пунктах (pt), где 1 пункт равен 1/72 дюйма. Ширина колонок привязана к «средней ширине символа» шрифта, установленного в макете по умолчанию.
Минимальный шаг изменения размера часто ограничен разрешением экрана (DPI), на котором работает система (обычно это 96 DPI). Платформа старается привязать границы ячейки к физическому пикселю, из-за чего возникает дискретность. Точность табличного документа составляет примерно 1/4 мм (0.25 мм). Любые значения «между» этими порогами будут округляться. Если ваша этикетка требует точности до сотых, стандартными средствами одного лишь свойства ВысотаСтроки этого добиться невозможно.
Рассмотрим самый эффективный программный метод — распределение погрешности. Если мы не можем сделать все строки одинаково «идеальными», мы будем корректировать каждую N-ю строку так, чтобы суммарная высота блока этикеток соответствовала физическому листу.
Допустим, нам нужна высота строки 72.80, а система позволяет установить только 72.75. Разница составляет 0.05. Разберем по шагам, как это реализовать в коде:
Пример логики расчета (для 5 этикеток):
Цель: 5 строк по 72.80 = 364.00 в сумме.
Реальность: 4 строки по 72.75 + 1 строка по 73.00 = 291 + 73 = 364.00.
Посмотрим на пример программной реализации:
// Пример корректировки высоты строк в цикле
НакопленнаяОшибка = 0;
ЦелеваяВысота = 72.80;
ДопустимыйШаг = 0.25;
Для Итератор = 1 По КоличествоЭтикеток Цикл
Область = Макет.ПолучитьОбласть("Этикетка");
// Выводим область...
ТабДок.Вывести(Область);
ТекущаяСтрока = ТабДок.Область(ТабДок.ВысотаТаблицы, , ТабДок.ВысотаТаблицы, );
Если НакопленнаяОшибка >= ДопустимыйШаг Тогда
ТекущаяСтрока.ВысотаСтроки = 72.75 + ДопустимыйШаг;
НакопленнаяОшибка = НакопленнаяОшибка - ДопустимыйШаг;
Иначе
ТекущаяСтрока.ВысотаСтроки = 72.75;
НакопленнаяОшибка = НакопленнаяОшибка + (ЦелеваяВысота - 72.75);
КонецЕсли;
КонецЦикла;
Проанализируем другой подход, который часто выручает, когда макет «ползет» целиком. У объекта ТабличныйДокумент есть свойство МасштабПечати. Платформа позволяет записывать туда дробные значения программно, даже если через интерфейс это сделать сложно.
Если ваши этикетки стабильно уменьшаются к концу листа, попробуйте установить масштаб чуть больше 100%. Например:
ТабДок.МасштабПечати = 100.5; // Увеличение на полпроцента может скомпенсировать сдвиг
Важный момент: результат будет сильно зависеть от драйвера конкретного принтера. Рекомендуем протестировать значения с шагом 0.1.
Выясним еще одну хитрость, используемую профессиональными разработчиками макетов. Вместо того чтобы задавать одной ячейке ширину 51.5 мм, можно создать макет, состоящий из множества очень узких колонок (например, шириной 0.1). Для формирования одной этикетки вы объединяете нужное количество таких микро-колонок.
Почему это работает? Алгоритм распределения ширины при печати в 1С при работе с объединенными ячейками ведет себя иначе. Суммарная погрешность при объединении 50 мелких интервалов часто оказывается ниже, чем попытка выставить размер одной большой ячейки «в лоб». Это требует кропотливой работы с макетом в конфигураторе, но дает максимально предсказуемый результат.
Поскольку ширина колонок в 1С привязана к размеру шрифта, попробуем изменить стандартный шрифт макета. Если в свойствах макета (или в стиле Текст) изменить шрифт с Arial 10 на Arial 7, дискретность (шаг) изменения ширины колонки изменится. Это позволит более точно «попадать» в нужные миллиметры при ручной настройке в конфигураторе.
Если прямая печать из 1С на принтер (через GDI+) искажает размеры, попробуйте метод сохранения в файл. Платформа 1С при выполнении метода Записать(ИмяФайла, ТипФайлаТабличногоДокумента.PDF) использует собственный движок формирования координат, который часто работает точнее системных драйверов печати.
Алгоритм действий будет следующим:
ТабличныйДокумент.Этот способ практически всегда гарантирует попадание в миллиметры, так как исключает влияние «технологических полей» 1С при непосредственной отправке на печать.
Чтобы минимизировать искажения, всегда проверяйте следующие настройки в макете и коде:
Ровно (в коде: ТипВысотыСтроки.Ровно). Если оставить значение Авто, 1С может «раздувать» ячейку в зависимости от содержимого, что мгновенно собьет разметку всего листа.Размещать: Обрезать для ячеек, чтобы текст внутри не провоцировал изменение геометрии строки.Проанализировав все вышеперечисленные методы, можно сделать вывод: если вам нужна идеальная точность, используйте комбинацию программной корректировки каждой N-й строки (Решение 1) и печать через PDF (Решение 5). Это позволит добиться типографской точности даже на обычном офисном оборудовании.