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