Печать макета 1С из кода и из формы: от области до принтера

· 9 мин

Содержание

Чтобы вывести макет на печать в 1С 8.3, на сервере создают ТабличныйДокумент, получают макет через ПолучитьМакет(), по очереди выводят в документ заполненные области методом Вывести(), а на клиенте вызывают Показать() для предпросмотра или Напечатать() для отправки на принтер. Всё остальное — параметры страницы, выбор принтера, число копий — задаётся свойствами того же табличного документа.

Механизм общий для платформы и не зависит от конфигурации. Различается только обёртка: в типовых решениях на БСП печать идёт через подсистему «Печать», а в своей обработке вы пишете вызовы сами. Разберём оба пути, а также то, что ломается чаще всего.

Что проверить до первой печати: принтер, драйвер, страница

1С не управляет принтером напрямую. Платформа отдаёт задание операционной системе, поэтому половина проблем решается не в коде.

Перед отладкой убедитесь:

  • 🖨️ принтер установлен в Windows у того пользователя, под которым запущена 1С, и печатает тестовую страницу;
  • 📄 в драйвере выставлен нужный формат бумаги (A4, а не Letter) — иначе поля съезжают на 5–6 мм;
  • 🌐 на терминальном сервере принтер пробрасывается в сеанс RDP и виден в списке принтеров сеанса;
  • 🔢 у пользователя есть права на сам принтер, если он сетевой.

В пользовательском режиме любой открытый табличный документ печатается через главное меню (кнопка с тремя полосками в левом верхнем углу) → Файл → Печать или сочетанием Ctrl+P. Там же есть Предварительный просмотр и Параметры страницы. Это быстрый способ понять, виноват макет или принтер: если обычная выгрузка списка печатается нормально, а ваша форма — нет, ищите причину в макете.

Параметры страницы, заданные пользователем вручную, по умолчанию живут только до закрытия документа. Чтобы 1С их запоминала, нужен ключ параметров печати — о нём ниже.

Как получить макет и заполнить табличный документ в коде

Макет — это шаблон из областей: «Заголовок», «Шапка», «Строка», «Подвал». Каждую область вы копируете в документ столько раз, сколько нужно, подставляя данные.

Где взять макет

ОткудаВызовГде выполнять
Макет объекта (документа, обработки)ПолучитьМакет("ИмяМакета") в модуле объекта или менеджерана сервере
Из модуля формыРеквизитФормыВЗначение("Объект").ПолучитьМакет("ИмяМакета")&НаСервере
Через менеджерДокументы.РеализацияТоваровУслуг.ПолучитьМакет("ИмяМакета")на сервере
Общий макетПолучитьОбщийМакет("ИмяМакета")на сервере

Ячейки макета заполняются одним из трёх способов (свойство «Заполнение» в палитре свойств ячейки):

  • Текст — выводится как есть;
  • Параметр — ячейка целиком берёт значение параметра с указанным именем;
  • Шаблон — текст со вставками в квадратных скобках: Счёт № [Номер] от [Дата].

Минимальный рабочий пример

Процедура формирует документ на сервере и возвращает его на клиент:

&НаСервереБезКонтекста
Функция СформироватьПечатнуюФорму(Ссылка)

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

    Макет = Документы.РеализацияТоваровУслуг.ПолучитьМакет("МояНакладная");

    ОбластьШапка  = Макет.ПолучитьОбласть("Шапка");
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");

    ОбластьШапка.Параметры.Номер = Ссылка.Номер;
    ОбластьШапка.Параметры.Дата  = Формат(Ссылка.Дата, "ДЛФ=D");
    ТабДок.Вывести(ОбластьШапка);

    НомерСтроки = 0;
    Для Каждого СтрокаТЧ Из Ссылка.Товары Цикл
        НомерСтроки = НомерСтроки + 1;
        ОбластьСтрока.Параметры.Заполнить(СтрокаТЧ);
        ОбластьСтрока.Параметры.НомерСтроки = НомерСтроки;
        ТабДок.Вывести(ОбластьСтрока);
    КонецЦикла;

    ОбластьПодвал.Параметры.Сумма = Ссылка.СуммаДокумента;
    ТабДок.Вывести(ОбластьПодвал);

    Возврат ТабДок;

КонецФункции

Параметры.Заполнить() раскладывает значения по совпадающим именам: если в области есть параметры Номенклатура, Количество, Цена, Сумма, они заполнятся из одноимённых колонок табличной части. Параметры без пары просто останутся пустыми.

Если присвоить значение параметру, которого в области нет (Параметры.Номре = …), код упадёт с ошибкой Поле объекта не обнаружено. Сверяйте имена в макете и в коде буква в букву.

Для вывода областей рядом, а не друг под другом, есть ТабДок.Присоединить(Область). Так собирают, например, две копии квитанции на одном листе.

Вывод макета на печать: предпросмотр, принтер без диалога, PDF

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

СпособКод на клиентеКогда подходит
ПредпросмотрТабДок.Показать("Накладная")человек проверит и сам нажмёт «Печать»
Диалог печатиТабДок.Напечатать(РежимИспользованияДиалогаПечати.Использовать)нужен выбор принтера и копий
Сразу на принтерТабДок.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать)массовая печать, этикетки, касса
ФайлТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.PDF)отправка по почте, архив

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

&НаКлиенте
Процедура ПечатьНакладной(Команда)

    ТабДок = СформироватьПечатнуюФорму(Объект.Ссылка);
    ТабДок.ИмяПринтера = "Kyocera ECOSYS M2040dn";
    ТабДок.КоличествоЭкземпляров = 2;
    ТабДок.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);

КонецПроцедуры

Имя принтера пишут точно так, как оно показано в Windows. Если такого принтера на машине пользователя нет, задание уйдёт не туда или не уйдёт вовсе. Надёжнее хранить имя в настройках пользователя, а не зашивать в код.

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

Печать в типовых конфигурациях: БСП, расширения и внешние формы

В БП 3.0, ЗУП 3.1, УТ 11 и других решениях на БСП печать устроена через подсистему «Печать». Команда «Печать» на форме документа вызывает процедуру Печать() в модуле менеджера, а результат открывается в общей форме печати документов с кнопками копий, сохранения и отправки.

Свою печатную форму там встраивают в два места модуля менеджера:

  1. В ДобавитьКомандыПечати(КомандыПечати) добавляют команду с идентификатором формы и представлением.
  2. В процедуре Печать(МассивОбъектов, ПараметрыПечати, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) формируют ТабличныйДокумент и передают его через УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию().

Код самой формы — те же ПолучитьМакет, ПолучитьОбласть, Вывести, что выше.

Не правьте макеты и модули типовой конфигурации напрямую: при следующем обновлении правки придётся переносить вручную. Есть три способа без снятия с поддержки:

  • 🧩 Расширение конфигурации . Заимствуете документ, добавляете свой макет и перехватываете нужные процедуры модуля менеджера. Обновления типовой части проходят без конфликтов.
  • 📦 Внешняя печатная форма (.epf). Подключается в Администрирование → Печатные формы, отчеты и обработки → Дополнительные отчеты и обработки. Подходит, когда форму нужно раздать нескольким базам.
  • ✏️ Правка макета без программиста. В Администрирование → Печатные формы, отчеты и обработки → Макеты печатных форм можно открыть типовой макет, поменять текст, шрифт или ширину колонки и сохранить свою версию. Её всегда можно сбросить к типовой.

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

Печать в тонком клиенте и в веб-клиенте: в чём разница

В тонком клиенте всё предсказуемо: документ приходит с сервера, печать идёт на принтеры той машины, где запущена 1С. ИмяПринтера, КоличествоЭкземпляров и печать без диалога работают так, как написаны в коде.

В веб-клиенте между 1С и принтером стоит браузер. Отсюда ограничения:

  • 🌐 окончательный диалог печати показывает браузер, и выбор принтера делается в нём;
  • 🚫 тихую печать без участия пользователя браузер обычно не пропускает — заложите в сценарий одно подтверждение;
  • 📐 поля и масштаб браузер может переопределить своими настройками — проверьте, что в его диалоге масштаб 100% и поля «по умолчанию» или «нет»;
  • 🔒 блокировщик всплывающих окон мешает открыть форму печати — добавьте адрес публикации базы в исключения.

Для веб-клиента практичнее отдавать пользователю PDF: сформировали файл на сервере, передали через временное хранилище, человек открыл и напечатал средствами просмотрщика. Вёрстка в этом случае не плывёт.

На терминальном сервере (RDP, RemoteApp) печать идёт как в тонком клиенте, но список принтеров — это принтеры сеанса. Если у сотрудника дома свой принтер, а в коде прописано имя офисного, задание уйдёт в офис.

Как подогнать макет под A4, ландшафт и узкую ленту

Размер и ориентацию задают свойствами табличного документа до вывода на печать:

ТабДок.РазмерСтраницы      = "A4";
ТабДок.ОриентацияСтраницы  = ОриентацияСтраницы.Ландшафт;
ТабДок.АвтоМасштаб         = Истина;
ТабДок.ПолеСлева           = 10;
ТабДок.ПолеСправа          = 10;
ТабДок.ПолеСверху          = 10;
ТабДок.ПолеСнизу           = 10;

Поля задаются в миллиметрах. АвтоМасштаб = Истина ужимает документ по ширине страницы — удобно, когда в отчёт добавили колонку и он перестал влезать. Если нужен фиксированный масштаб, вместо этого ставят МасштабПечати, например 85.

Таблица на несколько листов

Чтобы строка таблицы не разрывалась между страницами, перед выводом проверяют, поместится ли она вместе с подвалом:

МассивОбластей = Новый Массив;
МассивОбластей.Добавить(ОбластьСтрока);
МассивОбластей.Добавить(ОбластьПодвал);

Если Не ТабДок.ПроверитьВывод(МассивОбластей) Тогда
    ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
    ТабДок.Вывести(ОбластьШапкаТаблицы);
КонецЕсли;
ТабДок.Вывести(ОбластьСтрока);

Так на каждом новом листе повторяется шапка таблицы, а итог не остаётся одиноко на последней странице. Более простой вариант — свойство ПовторятьПриПечатиСтроки, которому передают область строк шапки: платформа сама продублирует её на каждом листе.

Разные устройства — разные макеты

УстройствоЧто учесть в макете
Лазерный принтер A4ширина всех колонок вместе с полями не больше 210 мм (портрет) или 297 мм (ландшафт)
Принтер этикетокотдельный макет под размер этикетки, размер страницы задаётся в драйвере
Чековая лента 58/80 ммодна узкая колонка, крупный шрифт, без рамок и заливок
Матричный принтерпростые шрифты, минимум рамок: тонкие линии пропечатываются плохо

Один универсальный макет на все случаи обычно хуже двух простых. Держите отдельный макет под каждый формат и выбирайте нужный в коде по настройке.

Почему макет печатается не так: диагностика ошибок

Большинство сбоев видны ещё в предпросмотре. Поэтому первым делом открывайте документ через Показать() и смотрите, где именно расходится картинка.

Диагностика: выберите симптом

Если предпросмотр правильный, а на бумаге всё сдвинуто, причина почти всегда в драйвере: неверный формат бумаги или непечатаемые поля принтера больше, чем поля документа. Увеличьте ПолеСлева и ПолеСверху на 3–5 мм и сравните.

Частые вопросы

Можно ли напечатать сразу несколько документов одним заданием?
Да. Выведите формы всех документов в один ТабличныйДокумент, разделяя их ВывестиГоризонтальныйРазделительСтраниц(), и вызовите Напечатать() один раз. Так быстрее, чем печатать по документу.
Как сделать, чтобы 1С запоминала поля и ориентацию, которые выставил пользователь?
Задайте табличному документу свойство КлючПараметровПечати — уникальную строку для каждой печатной формы. Платформа сохранит настройки страницы под этим ключом и подставит их при следующей печати.
Как вставить в макет логотип или подпись?
Добавьте в макет рисунок и задайте ему картинку в конфигураторе. Если картинка меняется, например по организации, заполняйте её в коде через свойство Картинка рисунка в области перед выводом.
Где в конфигураторе быстро собрать первую печатную форму документа?
У документов есть конструктор печати: он создаёт макет с областями и процедуру печати по выбранным реквизитам. Дальше результат правят вручную под нужный вид.
Можно ли печатать по расписанию, без пользователя?
Регламентное задание выполняется на сервере, а там Напечатать() недоступен. Обычно в задании формируют PDF через Записать() и отправляют его по почте или кладут в папку, откуда печатает другой сервис.