Как программно сформировать и вывести макет отчета в 1С 8.3

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

При разработке отчетов в системе 1С:Предприятие 8.3 начинающие программисты часто сталкиваются с трудностями при попытке связать визуальную форму, программный код и макет. Основная сложность заключается в понимании того, где именно должен исполняться код и как правильно обращаться к объектам метаданных в условиях управляемого приложения. Разберем пошагово, как реализовать формирование отчета по кнопке и разберемся в архитектуре модулей.

Понимание контекста выполнения: Клиент и Сервер

Прежде чем писать код, проанализируем ситуацию с доступностью объектов. В управляемом приложении код разделен на две части: &НаКлиенте (то, что видит пользователь) и &НаСервере (где происходят основные вычисления и работа с базой данных).

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

Реализация вывода отчета в отдельное окно

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

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


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

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

Вывод отчета непосредственно на форму

Иногда требуется, чтобы результат отображался не в новом окне, а прямо внутри формы отчета. Для этого проанализируем ситуацию с реквизитами формы. Нам не нужно создавать Новый ТабличныйДокумент, вместо этого мы будем использовать существующий реквизит формы.

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

  1. В редакторе формы добавьте реквизит с типом ТабличныйДокумент (например, с именем Результат).
  2. Перетащите этот реквизит в элементы формы, чтобы создалось Поле табличного документа.
  3. В коде обращайтесь к нему через Результат или ЭтотОбъект.Результат.

Пример кода для вывода на форму:


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

Разница между модулями отчета

Разберем подробнее, в каком модуле и что следует писать. Это один из самых частых вопросов при обучении 1С.

Модуль формы:

Здесь живет логика «интерфейса». Нажатия кнопок, изменение видимости полей, вопросы пользователю («Уверены, что хотите сформировать?»). В этом модуле мы пишем процедуры с префиксами &НаКлиенте и &НаСервере.

Модуль объекта:

Это сердце отчета. Здесь правильно размещать основную логику получения данных (Запросы). Если вы используете СКД (Систему компоновки данных), то именно в модуле объекта переопределяется событие ПриКомпоновкеРезультата. Использование модуля объекта позволяет вызывать формирование отчета из любой другой точки программы, не открывая его форму.

Модуль менеджера:

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

Работа с данными: где делать запрос?

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

Пример интеграции запроса:


&НаСервере
Функция СформироватьОтчетСЗапросом()
    
    ТабДок = Новый ТабличныйДокумент;
    Макет = ПолучитьМакет("МакетСРегистрами");
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   ПродажиОбороты.Номенклатура,
        |   ПродажиОбороты.КоличествоОборот
        |ИЗ
        |   РегистрНакопления.Продажи.Обороты(&Начало, &Конец) КАК ПродажиОбороты";
        
    Запрос.УстановитьПараметр("Начало", Объект.ДатаНачала);
    Запрос.УстановитьПараметр("Конец", КонецДня(Объект.ДатаОкончания));
    
    РезультатЗапроса = Запрос.Выполнить();
    Выборка = РезультатЗапроса.Выбрать();
    
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    
    Пока Выборка.Следующий() Цикл
        // Заполняем параметры области данными из запроса
        ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, Выборка);
        // Выводим заполненную область в документ
        ТабДок.Вывести(ОбластьСтрока);
    КонецЦикла;
    
    Возврат ТабДок;
    
КонецФункции

Рекомендации по использованию СКД

Хотя «ручной» вывод макета через ПолучитьОбласть() и Вывести() дает полный контроль над процессом, современным стандартом в 1С является Система компоновки данных (СКД). Мы рекомендуем по возможности использовать её, так как она автоматически берет на себя:

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

Резюме

Для успешного решения задачи программного вывода макета важно соблюдать три правила: первое — всегда разделять получение данных (сервер) и показ результата (клиент); второе — корректно обращаться к макету через контекст метаданных или объект; третье — не забывать использовать метод Показать() для объектов типа ТабличныйДокумент, созданных программно.

← На главную