Печать макета 1С из кода и из формы: от области до принтера
Содержание
Чтобы вывести макет на печать в 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 и других решениях на БСП печать устроена через подсистему «Печать». Команда «Печать» на форме документа вызывает процедуру Печать() в модуле менеджера, а результат открывается в общей форме печати документов с кнопками копий, сохранения и отправки.
Свою печатную форму там встраивают в два места модуля менеджера:
- В
ДобавитьКомандыПечати(КомандыПечати)добавляют команду с идентификатором формы и представлением. - В процедуре
Печать(МассивОбъектов, ПараметрыПечати, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода)формируютТабличныйДокументи передают его черезУправлениеПечатью.ВывестиТабличныйДокументВКоллекцию().
Код самой формы — те же ПолучитьМакет, ПолучитьОбласть, Вывести, что выше.
Не правьте макеты и модули типовой конфигурации напрямую: при следующем обновлении правки придётся переносить вручную. Есть три способа без снятия с поддержки:
- 🧩 Расширение конфигурации . Заимствуете документ, добавляете свой макет и перехватываете нужные процедуры модуля менеджера. Обновления типовой части проходят без конфликтов.
- 📦 Внешняя печатная форма (.epf). Подключается в
Администрирование → Печатные формы, отчеты и обработки → Дополнительные отчеты и обработки. Подходит, когда форму нужно раздать нескольким базам. - ✏️ Правка макета без программиста. В
Администрирование → Печатные формы, отчеты и обработки → Макеты печатных формможно открыть типовой макет, поменять текст, шрифт или ширину колонки и сохранить свою версию. Её всегда можно сбросить к типовой.
Если нужна только косметика — логотип, подпись, другой шрифт, — начните с третьего способа. Расширение оправдано, когда меняется состав данных или логика заполнения.
Печать в тонком клиенте и в веб-клиенте: в чём разница
В тонком клиенте всё предсказуемо: документ приходит с сервера, печать идёт на принтеры той машины, где запущена 1С. ИмяПринтера, КоличествоЭкземпляров и печать без диалога работают так, как написаны в коде.
В веб-клиенте между 1С и принтером стоит браузер. Отсюда ограничения:
- 🌐 окончательный диалог печати показывает браузер, и выбор принтера делается в нём;
- 🚫 тихую печать без участия пользователя браузер обычно не пропускает — заложите в сценарий одно подтверждение;
- 📐 поля и масштаб браузер может переопределить своими настройками — проверьте, что в его диалоге масштаб 100% и поля «по умолчанию» или «нет»;
- 🔒 блокировщик всплывающих окон мешает открыть форму печати — добавьте адрес публикации базы в исключения.
Для веб-клиента практичнее отдавать пользователю PDF: сформировали файл на сервере, передали через временное хранилище, человек открыл и напечатал средствами просмотрщика. Вёрстка в этом случае не плывёт.
На терминальном сервере (RDP, RemoteApp) печать идёт как в тонком клиенте, но список принтеров — это принтеры сеанса. Если у сотрудника дома свой принтер, а в коде прописано имя офисного, задание уйдёт в офис.
Как подогнать макет под A4, ландшафт и узкую ленту
Размер и ориентацию задают свойствами табличного документа до вывода на печать:
ТабДок.РазмерСтраницы = "A4";
ТабДок.ОриентацияСтраницы = ОриентацияСтраницы.Ландшафт;
ТабДок.АвтоМасштаб = Истина;
ТабДок.ПолеСлева = 10;
ТабДок.ПолеСправа = 10;
ТабДок.ПолеСверху = 10;
ТабДок.ПолеСнизу = 10;
Поля задаются в миллиметрах. АвтоМасштаб = Истина ужимает документ по ширине страницы — удобно, когда в отчёт добавили колонку и он перестал влезать. Если нужен фиксированный масштаб, вместо этого ставят МасштабПечати, например 85.
Таблица на несколько листов
Чтобы строка таблицы не разрывалась между страницами, перед выводом проверяют, поместится ли она вместе с подвалом:
МассивОбластей = Новый Массив;
МассивОбластей.Добавить(ОбластьСтрока);
МассивОбластей.Добавить(ОбластьПодвал);
Если Не ТабДок.ПроверитьВывод(МассивОбластей) Тогда
ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
ТабДок.Вывести(ОбластьШапкаТаблицы);
КонецЕсли;
ТабДок.Вывести(ОбластьСтрока);
Так на каждом новом листе повторяется шапка таблицы, а итог не остаётся одиноко на последней странице. Более простой вариант — свойство ПовторятьПриПечатиСтроки, которому передают область строк шапки: платформа сама продублирует её на каждом листе.
Разные устройства — разные макеты
| Устройство | Что учесть в макете |
|---|---|
| Лазерный принтер A4 | ширина всех колонок вместе с полями не больше 210 мм (портрет) или 297 мм (ландшафт) |
| Принтер этикеток | отдельный макет под размер этикетки, размер страницы задаётся в драйвере |
| Чековая лента 58/80 мм | одна узкая колонка, крупный шрифт, без рамок и заливок |
| Матричный принтер | простые шрифты, минимум рамок: тонкие линии пропечатываются плохо |
Один универсальный макет на все случаи обычно хуже двух простых. Держите отдельный макет под каждый формат и выбирайте нужный в коде по настройке.
Почему макет печатается не так: диагностика ошибок
Большинство сбоев видны ещё в предпросмотре. Поэтому первым делом открывайте документ через Показать() и смотрите, где именно расходится картинка.
Если предпросмотр правильный, а на бумаге всё сдвинуто, причина почти всегда в драйвере: неверный формат бумаги или непечатаемые поля принтера больше, чем поля документа. Увеличьте ПолеСлева и ПолеСверху на 3–5 мм и сравните.