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

· 9 мин

Содержание

Программное заполнение в 1С сводится к трём действиям: получить макет, подставить в его области параметры и вывести результат в объект ТабличныйДокумент. Так формируют печатные формы документов, реестры и отчёты прямо кодом — без системы компоновки данных.

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

Если нужна не печатная форма, а гибкая выборка с группировками и отбором, обычно берут СКД. Но когда разметка фиксированная (бланк, акт, реестр с жёсткими колонками), ручной вывод в табличный документ проще и предсказуемее.

Что готовим до начала заполнения

Перед первой строкой кода нужны две вещи: сам макет с областями и данные, которыми вы его наполните.

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

Данные удобнее собрать заранее в один источник, по которому пойдёт цикл:

  • 📊 запрос — если данные лежат в таблицах базы (документы, регистры, справочники);
  • 📋 таблица значений — если строки формируются в коде;
  • 🧱 выборка из запроса (Запрос.Выполнить().Выбрать()) — самый частый вариант для реестров.

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

Пример подготовки выборки:

Запрос = Новый Запрос;
Запрос.Текст =
    "ВЫБРАТЬ
    |    Расчёты.Контрагент КАК Контрагент,
    |    Расчёты.СуммаОстаток КАК Долг
    |ИЗ
    |    РегистрНакопления.ВзаиморасчётыСКонтрагентами.Остатки КАК Расчёты
    |УПОРЯДОЧИТЬ ПО
    |    Контрагент";
Выборка = Запрос.Выполнить().Выбрать();

Макет, области и типы заполнения ячеек

Макет получают методом ПолучитьМакет у менеджера объекта, которому он принадлежит:

Макет = Отчеты.РеестрДолгов.ПолучитьМакет("Макет");

Для обработки будет Обработки.ИмяОбработки.ПолучитьМакет(...), для общего макета — ПолучитьОбщийМакет("ИмяМакета"). Имя в кавычках — это синоним макета из конфигуратора, не его заголовок.

Область берут по имени, заданному при разметке:

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

ПолучитьОбласть каждый раз возвращает новую копию разметки. Поэтому одну и ту же область «Строка» можно получить один раз до цикла, а внутри цикла только менять её параметры — предыдущие выводы это не затрагивает.

Ключевой момент — как ячейка макета принимает значение. В свойствах ячейки поле «Заполнение» принимает одно из трёх значений:

ЗаполнениеЧто происходитКогда применять
ТекстСтатичный текст, подстановки нетЗаголовки, подписи, шапка колонок
ПараметрВсё содержимое ячейки заменяется значением параметраЧисла, даты, ссылки — одно значение на ячейку
ШаблонТекст с параметрами в квадратных скобках [Имя]«Накладная № [Номер] от [Дата]»

Самая частая ошибка новичка — вписать [Параметр] в ячейку с типом «Текст». Подстановки не будет: квадратные скобки сработают только у ячеек с заполнением «Шаблон».

Пошаговый вывод в ТабличныйДокумент

Алгоритм построения отчёта кодом один и тот же для любой разметки.

  1. Создать пустой табличный документ-приёмник.
  2. Вывести шапку, подставив её параметры.
  3. В цикле по данным выводить строку, обновляя параметры на каждой итерации.
  4. Вывести подвал с итогами.
  5. Показать или сохранить результат.
ТабДок = Новый ТабличныйДокумент;
Макет = Отчеты.РеестрДолгов.ПолучитьМакет("Макет");

ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьШапка.Параметры.Период = ТекущаяДата();
ТабДок.Вывести(ОбластьШапка);

ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
Итого = 0;
Пока Выборка.Следующий() Цикл
    ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, Выборка);
    ТабДок.Вывести(ОбластьСтрока);
    Итого = Итого + Выборка.Долг;
КонецЦикла;

ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");
ОбластьПодвал.Параметры.Итого = Итого;
ТабДок.Вывести(ОбластьПодвал);

ТабДок.Показать();

Разберём приёмы, без которых код выше не соберётся в аккуратный бланк.

Заполнение параметров пачкой. ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, Выборка) переносит в параметры области все одноимённые поля выборки. Имена колонок запроса должны совпадать с именами параметров в макете — тогда не нужно присваивать каждое поле вручную. Когда имена не совпадают, присваивайте точечно: ОбластьСтрока.Параметры.Сумма = Выборка.Долг;.

Вывести против Присоединить. Вывести(Область) ставит область под предыдущей — так растёт таблица сверху вниз. Присоединить(Область) ставит область справа от предыдущей — так собирают широкие отчёты по колонкам-периодам (январь, февраль, март в одну строку).

Группировки строк. Чтобы в готовом документе строки сворачивались по разделам, оберните вывод группы:

ТабДок.НачатьГруппуСтрок("Группа", Истина);
// здесь вывод строк группы
ТабДок.ЗакончитьГруппуСтрок();

Второй параметр Истина — группа изначально раскрыта.

Оформление: цвет, шрифт, границы и формат чисел

Условное оформление в табличном документе задают прямо в коде — проверяете условие и меняете свойства ячейки перед выводом строки. Встроенного механизма условного оформления, как у СКД или динамического списка, здесь нет.

Чтобы обратиться к конкретной ячейке строки, задайте ей имя в редакторе макета (свойство «Имя» ячейки). Тогда до вывода области можно подкрасить нужное поле:

Пока Выборка.Следующий() Цикл
    ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, Выборка);

    Если Выборка.Долг > 0 Тогда
        ОбластьСтрока.Области.Долг.ЦветТекста = Новый Цвет(200, 0, 0);
        ОбластьСтрока.Области.Долг.Шрифт = Новый Шрифт(, , Истина); // жирный
    КонецЕсли;

    ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;

Полезные свойства ячейки и области:

  • 🎨 ЦветФона = Новый Цвет(255, 245, 200) — заливка;
  • 🖊 ЦветТекста = Новый Цвет(200, 0, 0) — цвет шрифта;
  • B Шрифт = Новый Шрифт("Arial", 10, Истина) — третий параметр включает жирное начертание;
  • ▭ ГраницаСнизу = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная, 1) — нижняя рамка.

С числами есть нюанс. Чтобы сумма в документе выглядела как 1 250,00, а не 1250, задайте формат в свойстве «Формат» ячейки макета либо передавайте в параметр уже отформатированную строку:

ОбластьПодвал.Параметры.Итого = Формат(Итого, "ЧДЦ=2; ЧРД=','; ЧГ=' '");

💡 Формат лучше задавать в макете: тогда значение остаётся числом, и Excel при выгрузке посчитает его числом, а не текстом.

Ссылки, составные типы и расшифровка

Табличное поле нередко показывает ссылку — контрагента, номенклатуру, документ. Присваивайте ссылку параметру напрямую, система сама подставит её представление:

ОбластьСтрока.Параметры.Контрагент = Выборка.Контрагент;

В ячейке появится наименование. Если нужно именно строковое представление (например, для склейки с другим текстом в шаблоне) — используйте Строка(Выборка.Контрагент).

Составные типы. Когда параметр может принимать значения разных типов (в одной колонке и документы, и элементы справочника), ничего особенного делать не нужно — присваивайте значение как есть. Если тип параметра в макете составной, он корректно отобразит любое из допустимых значений. Для пустого значения проверьте Значение = Неопределено или Не ЗначениеЗаполнено(Значение) и подставьте прочерк, иначе в бланке будет пустота.

Расшифровка. Чтобы по двойному клику в готовом отчёте открывался объект или происходил переход, заполните свойство Расшифровка. Для этого в макете у ячейки задают параметр расшифровки, а в коде присваивают ему значение:

ОбластьСтрока.Параметры.РасшифровкаСтроки = Выборка.Контрагент.Ссылка;

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

Отдельно стоит продумать даты и логические значения. Дату в бланке обычно выводят через формат (Формат(Выборка.Дата, "ДЛФ=D") — короткая дата), а булево значение — не как Истина/Ложь, а осмысленным текстом: «Да»/«Нет» или галочкой. Проверку Если Выборка.Признак Тогда ... КонецЕсли делают до вывода строки и кладут в параметр уже готовую строку.

Как вывести, напечатать и сохранить результат

Готовый документ можно показать на экране, отправить на печать или выгрузить в файл.

Для печатной формы перед показом обычно закрывают документ от редактирования и прячут служебную разметку:

ТабДок.ТолькоПросмотр = Истина;
ТабДок.ОтображатьСетку = Ложь;
ТабДок.ОтображатьЗаголовки = Ложь;
ТабДок.Показать("Реестр долгов");
  • ТолькоПросмотр запрещает править содержимое открытого документа;
  • ОтображатьСетку = Ложь убирает серую клетку, оставляя чистый бланк;
  • если шапка таблицы должна повторяться на каждом листе при печати, присвойте область шапки свойству ПовторениеПриПечатиСтрок.

Перед печатью настройте страницу, иначе широкий реестр разъедется на несколько листов:

ТабДок.ПараметрыСтраницы.Ориентация = ОриентацияСтраницы.Ландшафт;
ТабДок.АвтоМасштаб = Истина;
ТабДок.МасштабПоШиринеСтраницы = 1; // вписать по ширине в один лист

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

Сохранить документ в файл помогает метод Записать:

ТабДок.Записать("C:\Выгрузки\Реестр.xlsx", ТипФайлаТабличногоДокумента.XLSX);

Доступны форматы XLSX, XLS, PDF, MXL (родной формат 1С) и другие. ⚠️ На сервере путь пишется относительно сервера, а не рабочей станции пользователя — для веб-клиента и тонкого клиента файл отдают через ПоместитьФайл или механизм получения файлов, иначе пользователь его не увидит.

В типовых конфигурациях на базе БСП печатные формы правильнее встраивать через подсистему «Управление печатью»: там табличный документ возвращается из процедуры печати, а платформа сама собирает комплект, печать и предпросмотр. Прямой Показать() годится для разовых обработок и отладки.

Важна и сторона выполнения. Получение макета, запрос к базе и сборка документа из областей — это серверная работа, её выполняют в процедуре с директивой &НаСервере. А метод Показать() — клиентский: он открывает окно у пользователя. Поэтому типовой приём — собрать готовый ТабличныйДокумент на сервере, вернуть его на клиент и уже там вызвать Показать(). Если вынести всё формирование на клиент, на толстые реестры уйдёт заметно больше времени из-за обращений к базе через границу клиент — сервер.

Типичные ошибки программного заполнения

Ошибки в коде вывода почти всегда сводятся к нескольким симптомам. Диагностика — ниже.

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

Ещё два момента, которые ломают вывод не ошибкой, а неверным результатом:

  • ❌ Область получена внутри цикла, а параметры заданы снаружи. Если ПолучитьОбласть("Строка") стоит в цикле, но параметры присваиваются переменной, полученной до цикла, выведется пустая разметка. Держите получение области и заполнение параметров в одном месте.
  • ❌ Итог считается по ячейке документа, а не по данным. Накапливайте сумму в отдельной переменной по ходу цикла (как Итого в примере), а не пытайтесь прочитать её обратно из уже выведенных ячеек.

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

Чем программный вывод в макет отличается от СКД?
Макет с ручным выводом даёт полный контроль над разметкой и подходит для фиксированных бланков. СКД берёт на себя группировки, отборы и оформление, но навязывает свою структуру. Для акта или строгой печатной формы проще макет, для аналитического отчёта с настройками — СКД.
Можно ли заполнить готовый табличный документ, а не собирать из областей?
Да. К ячейкам открытого документа обращаются по адресу ТабДок.Область("R1C2") или по имени области и присваивают Текст, ЦветФона и прочее. Но для повторяющихся строк вывод из макета по областям удобнее и быстрее.
Как объединить ячейки программно?
Через ТабДок.Область(ВерхняяСтрока, ЛеваяКолонка, НижняяСтрока, ПраваяКолонка).Объединить(). Чаще объединение задают прямо в макете, а код только выводит готовую область.
Почему при выводе большого реестра документ формируется медленно?
Обычно причина не в выводе, а в том, что данные добираются из базы внутри цикла. Соберите всё одним запросом с итогами до начала вывода и обращайтесь только к выборке.
Как вывести документ сразу на принтер без показа?
У табличного документа есть метод Напечатать, которому передают режим использования принтера. Для фоновых заданий и серверной печати настраивают принтер по умолчанию и параметры страницы заранее.