При разработке печатных форм в 1С:Предприятии часто возникает задача экономии бумаги. Типичный пример — вывод двух экземпляров малоформатного документа (например, накладной или акта формата А5) на один физический лист А4 горизонтально («бок о бок»). Начинающие разработчики пытаются решить эту задачу «в лоб» с помощью метода Присоединить() объекта ТабличныйДокумент, однако сталкиваются с тем, что документ выводится некорректно: либо только в одном экземпляре, либо вторая копия уходит вниз, либо ломается вся сетка колонок.
В этой статье мы подробно разберем, почему метод Присоединить() ведет себя подобным образом, как заставить его работать правильно и какой альтернативный способ компоновки печатного листа является наиболее надежным и простым в реализации.
Рассмотрим стандартную ошибку, которую совершают при попытке скопировать документ вправо. Разработчик получает заполненный табличный документ и пытается программно считать его область, после чего вывести ее сначала методом Вывести(), а затем методом Присоединить(). Код выглядит следующим образом:
ОбщийТД = Новый ТабличныйДокумент;
ОбщийТД.Вывести(ТабличныйДокумент.ПолучитьОбласть(1, 1, ТабличныйДокумент.ВысотаТаблицы, ТабличныйДокумент.ШиринаТаблицы));
ОбщийТД.Присоединить(ТабличныйДокумент.ПолучитьОбласть(1, 1, ТабличныйДокумент.ВысотаТаблицы, ТабличныйДокумент.ШиринаТаблицы));
При запуске такого кода вторая копия документа либо вообще не выводится, либо «съезжает» вниз, нарушая всю разметку. Выясним основные причины этой проблемы.
ПолучитьОбласть() по координатам строк и колонок или передаем область целиком без указания конкретных именованных пересечений, платформа считает эту область неограниченной по ширине (с бесконечной правой границей). Метод Присоединить() по своей логике выводит новую область правее самой правой заполненной ячейки текущей строки. Если у первой области нет четкой правой границы, платформе просто некуда «присоединять» вторую часть, и она переносит ее вниз или игнорирует позиционирование.Присоединить() сетки колонок левой и правой частей пытаются объединиться в одну общую таблицу. Так как ширины колонок в исходном макете для разных строк различаются, 1С не может корректно сопоставить их по горизонтали. В результате вся разметка «плывет», колонки сжимаются или неестественно растягиваются.Если ваша печатная форма имеет простую структуру колонок (без использования индивидуальных форматов строк) и вы принципиально хотите использовать метод Присоединить(), вам необходимо жестко ограничить область как по вертикали, так и по горизонтали. Для этого в макете печатной формы должны быть определены не только именованные строки, но и именованные колонки.
Разберем по шагам, как правильно составить программный код для этого случая:
СтрокаТаблицы) и область колонок (например, КолонкиТаблицы).Вывести(), а вторую — методом Присоединить().Посмотрим на пример реализации кода:
// Получаем область макета с четким ограничением по ширине
ОбластьПечати = Макет.ПолучитьОбласть("СтрокаТаблицы|КолонкиТаблицы");
// Заполняем параметры первой копии
ОбластьПечати.Параметры.Товар = "Товар 1";
ОбщийТД.Вывести(ОбластьПечати);
// Заполняем параметры второй копии (для вывода справа)
ОбластьПечати.Параметры.Товар = "Товар 1";
ОбщийТД.Присоединить(ОбластьПечати);
Только при таком подходе платформа 1С четко поймет, где заканчивается правая граница первой копии и откуда нужно начать отрисовку второй.
Если печатная форма имеет сложную структуру (что характерно для большинства реальных документов в 1С), попытка склеить макет горизонтально через Присоединить() превратится в бесконечную борьбу с шириной ячеек. Существует гораздо более простое, изящное и надежное решение — использовать встроенные возможности масштабирования платформы 1С:Предприятие и драйвера принтера.
Вместо того чтобы вручную лепить две таблицы бок о бок в одном документе, мы можем вывести две копии документа друг за другом (вертикально), разделив их горизонтальным разделителем страниц, а затем указать платформе скомпоновать их при печати на один лист в ландшафтной ориентации.
Проанализируем этот алгоритм на примере кода:
ОбщийТД = Новый ТабличныйДокумент;
// 1. Формируем и выводим первый экземпляр документа
ТабличныйДокумент1 = СформироватьОдинЭкземпляр();
ОбщийТД.Вывести(ТабличныйДокумент1);
// 2. Вставляем разделитель страниц, чтобы программно разделить копии
ОбщийТД.ВывестиГоризонтальныйРазделительСтраниц();
// 3. Формируем и выводим второй экземпляр документа
ТабличныйДокумент2 = СформироватьОдинЭкземпляр();
ОбщийТД.Вывести(ТабличныйДокумент2);
// 4. Настраиваем параметры страницы для автоматической группировки
ОбщийТД.ОриентацияСтраницы = ОриентацияСтраницы.Ландшафт; // Поворачиваем лист
ОбщийТД.ЭкземпляровНаСтранице = 2; // Указываем разместить 2 страницы на 1 листе
ОбщийТД.АвтоМасштаб = Истина; // Включаем автоподгон под размер бумаги
Преимущества данного способа:
Если вы реализуете печать в конфигурации, построенной на управляемых формах с использованием Библиотеки стандартных подсистем (БСП), вы можете столкнуться с тем, что настройки ОбщийТД.ЭкземпляровНаСтранице = 2 и ландшафтная ориентация упорно игнорируются при выводе формы на экран.
Выясним причину этого поведения. Дело в том, что БСП при выводе табличного документа на форму печати автоматически проверяет наличие сохраненных настроек печати для конкретного пользователя и конкретного отчета/документа. За это отвечает свойство табличного документа ИмяПараметровПечати (или КлючПараметровПечати).
Если пользователь ранее уже печатал этот документ в обычном формате (1 экземпляр на странице, портретная ориентация), БСП прочитает эти настройки из системного хранилища и перезапишет ваши программные установки. Чтобы обойти это поведение, выполните следующие действия:
ОбщийТД.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_РеализацияТоваровУслуг_Накладная_2Экз";
Используя данные рекомендации, вы сможете быстро и безболезненно реализовывать любые сложные варианты компоновки печатных форм в своих прикладных решениях на платформе 1С:Предприятие 8.