Как изменить номер экземпляра при печати транспортной накладной в 1С

Программист 1С v8.3 (Обычные формы) Управленческий учет Торговля и дистрибуция
← На главную

При работе с первичными документами, особенно с транспортными накладными (ТН), часто возникает законодательное или внутреннее требование: на каждом экземпляре документа должен быть указан его порядковый номер (например, «Экземпляр № 1», «Экземпляр № 2» и так далее). Стандартный механизм печати 1С, использующий свойство КоличествоЭкземпляров объекта ТабличныйДокумент, в данном случае не подходит, так как принтер просто дублирует один и тот же сформированный образ, и текст в нем остается неизменным.

В этой статье мы подробно разберем, как программно реализовать вывод номера экземпляра, чтобы каждая копия документа была уникальной. Мы проанализируем различные подходы — от простых циклов до оптимизированного формирования единого пакета на печать.

Почему стандартная настройка копий не работает

Разберем типичную ситуацию: программист устанавливает значение ТабличныйДокумент.КоличествоЭкземпляров = 4; и отправляет документ на принтер. В этом случае 1С формирует одну страницу в памяти и передает драйверу принтера команду «напечатать это 4 раза». Поскольку формирование происходит один раз, мы никак не можем изменить содержимое ячейки «Номер экземпляра» для второй или третьей копии.

Чтобы решить эту задачу, нам необходимо пойти другим путем: сформировать один длинный табличный документ, который будет содержать в себе все необходимые копии одну за другой, разделенные разрывами страниц.

Метод 1: Формирование единого табличного документа в цикле

Это самый надежный и распространенный метод в среде 1С. Мы будем использовать цикл для заполнения областей макета и вывода их в итоговый документ. Рассмотрим по шагам, как это реализовать.

Шаг 1. Подготовка итогового документа и макета.

Сначала мы создаем пустой табличный документ, который в итоге будет отправлен на печать, и получаем макет нашей накладной.

Шаг 2. Запуск цикла по количеству копий.

Выясним, сколько экземпляров нужно напечатать (например, через запрос к пользователю или из настроек системы), и запустим цикл.

Разберем пример кода:


// Создаем итоговый документ
ТабДокИтоговый = Новый ТабличныйДокумент;
ТабДокИтоговый.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_ТРАНСПОРТНАЯ_НАКЛАДНАЯ";

// Определяем количество копий
КоличествоКопий = 4; 

Макет = ПолучитьМакет("МакетТН");
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");

Для НомерЭкземпляра = 1 По КоличествоКопий Цикл
    
    // Если это не первый экземпляр, добавляем разрыв страницы
    Если НомерЭкземпляра > 1 Тогда
        ТабДокИтоговый.ВывестиГоризонтальныйРазделительСтраниц();
    КонецЕсли;
    
    // Заполняем параметры шапки, включая номер экземпляра
    ОбластьШапка.Параметры.НомерЭкземпляраТекст = "Экземпляр № " + НомерЭкземпляра;
    // Здесь также заполняются остальные параметры (Организация, Контрагент и т.д.)
    ОбластьШапка.Параметры.Заполнить(ДанныеДляПечати);
    
    // Выводим заполненную область в итоговый документ
    ТабДокИтоговый.Вывести(ОбластьШапка);
    
    // Аналогично выводим строки таблицы и подвал
    // ...
    
КонецЦикла;

// Включаем разбор по копиям для удобства принтера
ТабДокИтоговый.РазборПоКопиям = Истина;
ТабДокИтоговый.Показать();

В данном примере функция ВывестиГоризонтальныйРазделительСтраниц() гарантирует, что каждый новый экземпляр начнется с нового листа бумаги. Это критически важно, так как транспортная накладная может занимать несколько страниц.

Метод 2: Оптимизация через копирование областей

Если печатная форма очень сложная, содержит много данных и расчетных полей, повторное формирование каждой копии "с нуля" в цикле может замедлить работу системы. В таком случае мы можем применить метод копирования уже заполненной области.

Проанализируем ситуацию: данные во всех экземплярах (кроме номера) идентичны. Мы можем один раз сформировать эталонный экземпляр в памяти, а затем просто дублировать его, меняя только одну ячейку.

Рассмотрим алгоритм действий:

  1. Формируем временный табличный документ для одного экземпляра.
  2. Заполняем его всеми данными из информационной базы.
  3. В основном цикле копируем этот документ в итоговый.
  4. Используем метод НайтиТекст() или прямое обращение к области, чтобы заменить номер экземпляра.

Пример реализации:


// Формируем эталон
ТабЭкземпляр = СформироватьОдинЭкземпляр(Данные); 

Для Индекс = 1 По КоличествоКопий Цикл
    Если Индекс > 1 Тогда
        ТабДокИтоговый.ВывестиГоризонтальныйРазделительСтраниц();
    КонецЕсли;
    
    // Находим область с текстом "Экземпляр №" и меняем ее
    ОбластьНомера = ТабЭкземпляр.НайтиТекст("Экземпляр №");
    Если ОбластьНомера <> Неопределено Тогда
        ОбластьНомера.Текст = "Экземпляр № " + Индекс;
    КонецЕсли;
    
    ТабДокИтоговый.Вывести(ТабЭкземпляр);
КонецЦикла;

Специфика транспортных накладных

Стоит отметить, что согласно Постановлению Правительства №2116, экземпляры транспортной накладной часто должны различаться не только цифрой, но и указанием того, кому предназначен данный лист. Например:

Для реализации такой логики лучше всего подготовить массив или соответствие, которое мы будем использовать в нашем основном цикле формирования документа.


Предназначение = Новый Массив;
Предназначение.Добавить(" (для грузоотправителя)");
Предназначение.Добавить(" (для грузополучателя)");
Предназначение.Добавить(" (для перевозчика)");
Предназначение.Добавить(" (дополнительный)");

Для Сч = 1 По КоличествоКопий Цикл
    // ... логика вывода ...
    ТекстПояснения = "";
    Если Сч <= Предназначение.Количество() Тогда
        ТекстПояснения = Предназначение[Сч - 1];
    КонецЕсли;
    
    ОбластьШапка.Параметры.НомерЭкземпляра = "Экземпляр № " + Сч + ТекстПояснения;
    // ...
КонецЦикла;

Важные технические нюансы

При реализации печати нескольких экземпляров в одном документе следует учитывать несколько моментов:

1. Колонтитулы: Если вы используете свойство ВерхнийКолонтитул или НижнийКолонтитул, помните, что они применяются ко всему табличному документу. Если вам нужно, чтобы в колонтитуле отображался номер экземпляра, стандартный механизм [&НомерСтраницы] не поможет, так как он будет считать сквозные страницы всего документа (например, 1-12). В этом случае номер экземпляра лучше выводить непосредственно в тело макета (в область шапки или подвала), а не в системный колонтитул.

2. Двусторонняя печать: Если принтер настроен на двустороннюю печать, использование ВывестиГоризонтальныйРазделительСтраниц() может привести к тому, что первый лист второго экземпляра напечатается на обороте последнего листа первого экземпляра. Чтобы этого избежать, количество страниц в одном экземпляре должно быть четным, либо нужно программно проверять количество страниц и добавлять пустой лист при необходимости.

3. Свойство РазборПоКопиям: Всегда устанавливайте ТабличныйДокумент.РазборПоКопиям = Истина;. Хотя в нашем случае мы и так формируем страницы по порядку, эта настройка помогает драйверам принтеров корректно обрабатывать задания большого объема.

Подведем итог: наиболее правильным и гибким способом вывода номера экземпляра в 1С является формирование единого ТабличногоДокумента внутри цикла. Это позволяет полностью контролировать содержимое каждой страницы и гарантирует корректный результат независимо от модели принтера и настроек его драйвера.

← На главную