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