Почему в типовых печатных формах 1С данные и макет не разделены и как это устроено?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке и модификации печатных форм в 1С (таких как ТТН, ТОРГ-12 или Счет-фактура) многие разработчики задаются вопросом: почему архитектура системы заставляет нас смешивать логику получения данных и визуальный вывод? Казалось бы, идеальная модель — это когда отдельная функция собирает структуру данных, а некий универсальный «движок» просто «натягивает» эти данные на макет. Однако в типовых конфигурациях мы постоянно видим процедурный код, где вывод каждой области перемежается логическими условиями Если... Тогда.

В этой статье мы подробно разберем технические и исторические причины такого устройства системы, выясним, какие ограничения платформы 1С:Предприятие мешают внедрению чистого разделения (MVC-подхода) в печать, и рассмотрим современные стандарты разработки в рамках БСП.

Исторический контекст и эволюция подходов

Рассмотрим ситуацию в ретроспективе. Процесс формирования печатных форм в 1С прошел несколько этапов эволюции. В ранних версиях 1С 7.7 и первых редакциях 8.0 печатные формы создавались максимально просто: данные извлекались прямо в процессе перебора строк документа, и тут же вызывался метод Вывести(). Понятия «Менеджер печати» или «Общие модули печати» практически отсутствовали.

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

  1. Обратная совместимость: Огромное количество типовых форм было написано годы назад. Переписывание их на новые «рельсы» требует колоссальных ресурсов при сомнительной выгоде для конечного пользователя.
  2. Простота входа: Процедурный метод формирования ТабличныйДокумент интуитивно понятен начинающим разработчикам. Нарисовал макет — вывел область — заполнил параметры.

Техническое ограничение: Контроль разбиения страниц

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

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


// Пример типичного алгоритма вывода с проверкой
МассивВыводимыхОбластей = Новый Массив;
МассивВыводимыхОбластей.Добавить(ОбластьСтрока);
МассивВыводимыхОбластей.Добавить(ОбластьПодвал);

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

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

Динамические макеты и изменяемая структура

Разберем ситуацию, когда макет печатной формы не является статичным. В современных конфигурациях (ERP, КА, УТ) формы часто зависят от настроек системы или функциональных опций. Например:

При процедурном подходе мы можем программно изменять макет «на лету» перед выводом:


ОбластьМакета = Макет.ПолучитьОбласть("Строка");
Если ВыводитьДопРеквизит Тогда
    ОбластьМакета.Области.ДопКолонка.Текст = "Значение";
Иначе
    // Скрываем или удаляем колонку программно
КонецЕсли;
ТабДок.Вывести(ОбластьМакета);

В модели, где «структура просто натягивается на макет», пришлось бы описывать сложную логику трансформации самого шаблона, что в терминах 1С (работа с объектом ТабличныйДокумент) гораздо сложнее, чем простое ветвление в коде.

Современный стандарт БСП: Компромиссное решение

Несмотря на вышеуказанные сложности, фирма «1С» в Библиотеке стандартных подсистем (БСП) пришла к определенному разделению. Посмотрим, как это реализовано в современных типовых решениях:

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

Проанализируем пример такого подхода:


// Шаг 1: Получение данных (Логика)
ДанныеДляПечати = СформироватьСтруктуруДанных(МассивОбъектов);

// Шаг 2: Формирование документа (Визуализация)
Для Каждого ДанныеОбъекта Из ДанныеДляПечати Цикл
    // Здесь только работа с макетом и областями
    ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
    ЗаполнитьЗначенияСвойств(ОбластьЗаголовок.Параметры, ДанныеОбъекта);
    ТабДок.Вывести(ОбластьЗаголовок);
КонецЦикла;

Почему не используются внешние шаблонизаторы?

Рассмотрим альтернативы, такие как шаблоны DOCX или PDF, которые действительно позволяют реализовать схему «данные + макет». В 1С есть механизм печати по шаблонам Microsoft Word. Там это работает именно так: в файле расставлены теги (например, {НомерДокумента}), и система их заменяет.

Однако этот метод имеет ряд критических недостатков для массовой печати:

Итоги и рекомендации

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

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

Таким образом, хотя «фабрика печатных форм» в ее идеальном виде не представлена в типовых решениях, следование стандартам БСП позволяет максимально приблизиться к чистому коду, сохраняя при этом гибкость управления печатным листом.

← На главную