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