Когда и зачем нужно применять метод Отчеты.ИмяОтчета.Создать() в 1С? Разбираемся в архитектуре и программной работе с СКД

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

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

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

Менеджер отчета vs Объект отчета: в чем принципиальная разница?

Для понимания логики работы платформы 1С важно четко разграничивать два типа программных сущностей:

  1. Менеджер отчета (доступен через Отчеты.ИмяОтчета) — это глобальный инструмент управления метаданными данного типа. Он существует в системе в единственном экземпляре. Через менеджер мы можем получить доступ к общим свойствам, макетам (не создавая сам отчет в памяти), открыть основную форму отчета или проверить права доступа текущего пользователя. Менеджер не хранит в себе состояние конкретного сеанса работы.
  2. Объект отчета (создается методом Отчеты.ИмяОтчета.Создать()) — это конкретный экземпляр отчета, выделенный в оперативной памяти сервера. Этот объект обладает собственным набором реквизитов, табличных частей, собственным модулем объекта с предопределенными событиями, а главное — индивидуальными свойствами СхемаКомпоновкиДанных и КомпоновщикНастроек.

Если нам нужно просто прочитать макет, хранящийся в отчете, создавать объект не требуется. Мы можем написать лаконичный код:


ИмяОтчета = "ПрайсЛист";
Макет = Отчеты[ИмяОтчета].ПолучитьМакет("Макет");

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

Сценарий 1: Программное формирование отчета на сервере (без открытия формы)

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

Именно здесь на помощь приходит создание объекта отчета. Мы создаем его программно, настраиваем параметры и выводим результат напрямую в табличный документ.

Рассмотрим пошагово, как выглядит этот процесс в коде:


// Шаг 1. Создаем объект отчета в памяти сервера
ОтчетОбъект = Отчеты.ПродажиПоВыручке.Создать();

// Шаг 2. Создаем чистый табличный документ, куда будет выведен результат
ТабДок = Новый ТабличныйДокумент;

// Шаг 3. Инициализируем процесс компоновки данных
// Метод СкомпоноватьРезультат выполняет запрос к БД, обрабатывает СКД и заполняет ТабДок
ОтчетОбъект.СкомпоноватьРезультат(ТабДок);

// Шаг 4. Сохраняем полученный результат на диск или отправляем почтой
ТабДок.Записать("C:\Reports\Sales_Report.pdf", ТипФайлаТабличногоДокумента.PDF);

Этот простой пример показывает базовую схему работы. Метод СкомпоноватьРезультат() берет настройки по умолчанию, выполняет все запросы СКД, формирует макет вывода и заполняет переданный ему ТабличныйДокумент.

Сценарий 2: Перехват события «ПриКомпоновкеРезультата»

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

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


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

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

Сценарий 3: Программная передача параметров и отборов (Ответ на вопросы участников форума)

Участники обсуждения справедливо поинтересовались: «А как передать параметры, которые пользователь обычно заполняет вручную на форме?» Для решения этой задачи мы должны обратиться к свойству объекта КомпоновщикНастроек. Именно он управляет тем, какие параметры и отборы будут применены при выполнении запросов СКД.

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


// Создаем объект отчета
ОтчетОбъект = Отчеты.ОстаткиТоваров.Создать();

// Получаем доступ к параметрам данных компоновщика настроек
ПараметрыДанных = ОтчетОбъект.КомпоновщикНастроек.Настройки.ПараметрыДанных;

// Ищем нужный параметр по его имени в СКД
ПараметрПериод = ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("КонецПериода"));

Если ПараметрПериод <> Неопределено Тогда
    // Задаем значение параметра
    ПараметрПериод.Значение = ТекущаяДата();
    // Обязательно взводим флаг использования параметра!
    ПараметрПериод.Использование = Истина;
КонецЕсли;

А что делать, если нужно наложить отбор по конкретному реквизиту (например, отобрать данные только по складу «Основной»)? Для этого мы динамически добавляем новый элемент отбора в коллекцию компоновщика настроек:


// Находим коллекцию элементов отбора
КоллекцияОтборов = ОтчетОбъект.КомпоновщикНастроек.Настройки.Отбор;

// Добавляем новый элемент отбора
НовыйОтбор = КоллекцияОтборов.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));

// Задаем левое значение отбора - поле СКД, по которому фильтруем
НовыйОтбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Склад");

// Задаем вид сравнения (Равно, ВГруппе, НеРавно и т.д.)
НовыйОтбор.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;

// Задаем правое значение отбора - конкретную ссылку на элемент справочника
НовыйОтбор.ПравоеЗначение = Справочники.Склады.НайтиПоНаименованию("Основной склад");

// Активируем отбор
НовыйОтбор.Использование = Истина;

Важное предупреждение: Существует тонкий нюанс при работе с управляемыми формами. Настройки компоновщика делятся на основные настройки схемы (Настройки) и настройки, которые выведены пользователю на форму (ПользовательскиеНастройки). Если вы программно создаете объект отчета, заполняете параметры в КомпоновщикНастроек.Настройки, а затем открываете форму этого отчета пользователю — он может увидеть пустые поля на экране! Это происходит потому, что платформа приоритетно отображает значения из ПользовательскиеНастройки. Для корректного заполнения параметров при интерактивном открытии формы лучше передавать параметры через структуру параметров формы при вызове метода ОткрытьФорму().

Сценарий 4: Использование реквизитов и табличных частей отчета

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

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


ОтчетОбъект = Отчеты.АнализПродаж.Создать();
// Заполняем реквизит объекта, созданный в конфигураторе
ОтчетОбъект.ПроводитьДополнительныйАнализ = Истина; 
ОтчетОбъект.СкомпоноватьРезультат(ТабДок);

Сценарий 5: Внешние печатные формы (В контексте ЗУП 3.1 и БСП)

В сообщении №5 участник форума упомянул использование отчетов для формирования печатных форм (Т-1, Т-5, Т-8 и др.) в конфигурации «Зарплата и управление персоналом». Действительно, Библиотека Стандартных Подсистем (БСП) активно использует этот подход.

Почему для печатных форм используются отчеты и метод Создать()?

Посмотрим, как выглядит программное создание объекта внешнего отчета из кода:


// Получаем двоичные данные файла .erf из хранилища (например, из справочника)
ДвоичныеДанныеФайла = ПолучитьДвоичныеДанныеВнешнегоОтчета(); 

// Помещаем во временное хранилище
АдресХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанныеФайла);

// Создаем объект внешнего отчета по адресу во временном хранилище
ИмяВнешнегоОтчета = ВнешниеОтчеты.Подключить(АдресХранилища);
ОбъектВнешнегоОтчета = ВнешниеОтчеты.Создать(ИмяВнешнегоОтчета);

// Теперь объектВнешнегоОтчета готов к работе так же, как и обычный встроенный отчет
ОбъектВнешнегоОтчета.СкомпоноватьРезультат(ТабДок);

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

Резюме: Краткий чек-лист разработчика

Подведем итог. Использовать метод Создать() и оперировать ОтчетОбъект необходимо в следующих случаях:

  1. Вы формируете отчет программно на сервере (в фоновом задании, регламентном задании, в обработчиках интеграционных HTTP/REST-сервисов).
  2. Вам необходимо программно заполнить параметры СКД, установить сложные отборы или динамически изменить группировки данных перед выводом отчета.
  3. Вы переопределяете стандартный вывод отчета в модуле объекта с помощью обработчика события ПриКомпоновкеРезультата.
  4. Вы работаете с механизмами БСП (внешние печатные формы, отчеты-плагины), где создание объектов отчетов происходит динамически по имени или из временного хранилища файлов .erf.

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

← На главную