Как программно настроить Универсальный отчет в 1С и выгрузить его в таблицу значений или табличный документ?

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

В практике разработки на платформе 1С:Предприятие 8 часто возникает необходимость автоматизировать формирование отчетов. Например, требуется настроить регулярную отправку отчета по электронной почте через регламентное задание или обработать данные готового отчета в кодовой логике, не выводя его на экран пользователю. Если отчет разработан на базе популярного механизма «Универсальный отчет» (широко используемого в конфигурациях на обычных формах, таких как УТ 10.3, УПП 1.3, КА 1.1), разработчики часто сталкиваются со сложностями при попытке программно получить данные.

В этой статье мы подробно разберем, как программно управлять настройками Универсального отчета, как вывести его в ТабличныйДокумент для последующего сохранения в файл (XLS, PDF), а также как получить "сырые" данные в виде ТаблицыЗначений для дальнейшей программной обработки.

Понимание архитектуры Универсального отчета

Прежде чем переходить к написанию кода, проанализируем, как устроен этот механизм. Типовой «Универсальный отчет» является надстройкой над стандартным объектом платформы ПостроительОтчета. Именно построитель отвечает за сборку текста запроса, работу с настройками (измерения, отборы, показатели, сортировка) и вывод результата.

Сам объект «Универсальный отчет» предоставляет разработчику удобный интерфейс (API) для манипулирования свойствами построителя. Зная это, мы можем управлять процессом формирования отчета на любом этапе.

Выделим три основных сценария решения нашей задачи:

  1. Прямое получение ТаблицыЗначений из результата запроса отчета.
  2. Программное формирование отчета в ТабличныйДокумент (с последующим сохранением в файл).
  3. Обратная конвертация готового ТабличногоДокумента в ТаблицуЗначений.

Рассмотрим каждый из этих сценариев подробнее с практическими примерами кода.


Решение 1. Прямая выгрузка Универсального отчета в Таблицу Значений

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

Выясним, как это сделать. У объекта УниверсальныйОтчет есть штатный экспортный метод ПолучитьРезультат(), который возвращает выполненный запрос с учетом всех примененных отборов и параметров. Этот результат мы можем легко выгрузить.

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


// 1. Создаем объект нужного отчета программно
ИмяОтчета = "Продажи";
ОтчетОбъект = Отчеты[ИмяОтчета].Создать();

// 2. Инициализируем начальные настройки отчета
ОтчетОбъект.УстановитьНачальныеНастройки();

// 3. При необходимости программно накладываем нужные нам отборы
ЭлементОтбора = ОтчетОбъект.УниверсальныйОтчет.ПостроительОтчета.Отбор["Контрагент"];
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.ВидСравнения = ВидСравнения.Равно;
ЭлементОтбора.Значение = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", "7700000000");

// 4. Получаем результат запроса напрямую из механизмов отчета
РезультатЗапроса = ОтчетОбъект.УниверсальныйОтчет.ПолучитьРезультат();

// 5. Выгружаем данные в Таблицу Значений
ТаблицаДанных = РезультатЗапроса.Выгрузить();

Важный нюанс: По умолчанию в построителе отчета могут быть настроены группировки (секция ИТОГИ ПО). При стандартной выгрузке через метод Выгрузить() вы получите плоскую таблицу, содержащую как детальные записи, так и строки с итогами по группировкам. Если вам нужны исключительно детальные записи без итогов, рекомендуется обойти результат запроса с прямым обходом:


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

// Для автоматического создания колонок в ТЗ можно временно выгрузить структуру
ТаблицаДетальныхЗаписей = РезультатЗапроса.Выгрузить();
ТаблицаДетальныхЗаписей.Очистить(); // Очищаем от строк, сохраняя колонки

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

Решение 2. Программное формирование отчета в Табличный Документ

Рассмотрим ситуацию, когда отчет необходимо сформировать именно в таком виде, в каком его видит пользователь на экране (с оформлением, группировками и шапками), записать в файл XLS/PDF и отправить по почте. Этот сценарий часто применяется в фоновых регламентных заданиях.

Разберем по шагам, как очистить предопределенные пользовательские настройки, задать структуру отчета программно и вывести его.


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

// Загружаем базовые настройки отчета
ОтчетОбъект.УстановитьНачальныеНастройки();

// Отключаем автоматическое восстановление настроек пользователя при открытии
ОтчетОбъект.УниверсальныйОтчет.мВосстанавливатьНастройкиПриОткрытии = Ложь;

// Очищаем старые измерения строк, колонок и выбранные поля, чтобы настроить их с нуля
Построитель = ОтчетОбъект.УниверсальныйОтчет.ПостроительОтчета;

Пока Построитель.ИзмеренияСтроки.Количество() > 0 Цикл
    Построитель.ИзмеренияСтроки.Удалить(Построитель.ИзмеренияСтроки[0]);
КонецЦикла;

Пока Построитель.ИзмеренияКолонки.Количество() > 0 Цикл
    Построитель.ИзмеренияКолонки.Удалить(Построитель.ИзмеренияКолонки[0]);
КонецЦикла;

Пока Построитель.ВыбранныеПоля.Количество() > 0 Цикл
    Построитель.ВыбранныеПоля.Удалить(Построитель.ВыбранныеПоля[0]);
КонецЦикла;

// Настраиваем показатели (очищаем и добавляем только нужные)
ОтчетОбъект.УниверсальныйОтчет.Показатели.Строки.Очистить();

// Включаем детальные записи (вывод строк без обязательной группировки)
ОтчетОбъект.УниверсальныйОтчет.ВыводитьДетальныеЗаписи = Истина;

// Добавляем дополнительные поля и определяем их положение (1 - в отдельной колонке)
ОтчетОбъект.УниверсальныйОтчет.ДобавитьДополнительноеПоле("Контрагент.Код", , 1);
ОтчетОбъект.УниверсальныйОтчет.ДобавитьДополнительноеПоле("Контрагент", , 1);
ОтчетОбъект.УниверсальныйОтчет.ДобавитьДополнительноеПоле("ОтгрузкаЗапрещена", , 1);

// Добавляем отбор (например, выбираем только тех клиентов, у которых заблокирована отгрузка)
ОтчетОбъект.УниверсальныйОтчет.ДобавитьОтбор("Контрагент.ОтгрузкаЗапрещена", Истина, ВидСравнения.Равно, Истина);

// Установка параметров периода (если отчет их поддерживает)
ОтчетОбъект.УниверсальныйОтчет.ДатаНач = НачалоДня(ТекущаяДата() - 86400); // Вчера
ОтчетОбъект.УниверсальныйОтчет.ДатаКон = КонецДня(ТекущаяДата() - 86400);

// Формируем отчет в подготовленный Табличный Документ
ОтчетОбъект.СформироватьОтчет(ТабДок);

// Сохраняем результат на диск во временный каталог в формате Excel
ПутьКФайлу = КаталогВременныхФайлов() + "BlockList.xls";
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLS);

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


Решение 3. Обратное преобразование готового Табличного Документа в Таблицу Значений

Что делать, если отчет формируется сложным образом через внутренние алгоритмы, накладывает собственное оформление, объединяет ячейки, и выгрузить его простым запросом невозможно? Но при этом вам на выходе крайне необходима именно "чистая" ТаблицаЗначений.

Перебирать ячейки табличного документа в циклах Для Строка = 1 По ВысотаТаблицы... — это очень медленный процесс, который сильно нагружает систему. К счастью, в платформе 1С предусмотрен мощный инструмент — ОписаниеИсточникаДанных. Он позволяет мгновенно преобразовать область ячеек табличного документа в полноценную таблицу значений.

Проанализируем пример выполнения этой операции:


// Предположим, что ТабДок уже сформирован вызовом метода СформироватьОтчет()

// 1. Определяем границы заполненной области табличного документа
КоличествоСтрок = ТабДок.ВысотаТаблицы;
КоличествоКолонок = ТабДок.ШиринаТаблицы;

// Если в отчете есть шапка, то область данных нужно начать ниже, например со строки 5
// Предположим, что строка с именами колонок находится на уровне строки 4
ОбластьДанных = ТабДок.Область(4, 1, КоличествоСтрок, КоличествоКолонок);

// 2. Создаем описание источника данных на основании этой области
ИсточникДанных = Новый ОписаниеИсточникаДанных(ОбластьДанных);
ИсточникДанных.Колонки.Контрагент.Имя = "Контрагент"; // Можно переопределить имена

// 3. Используем ПостроительЗапроса для быстрой конвертации
ПостроительКонвертера = Новый ПостроительЗапроса;
ПостроительКонвертера.ИсточникДанных = ИсточникДанных;
ПостроительКонвертера.Выполнить();

// 4. Получаем готовую Таблицу Значений
ТаблицаИзТабДока = ПостроительКонвертера.Результат.Выгрузить();

Преимущества данного метода:


Решение 4. Создание отчета со своим произвольным запросом "на лету"

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

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


// Создаем экземпляр базового универсального отчета
ОтчетСозданный = Отчеты.УниверсальныйОтчет.Создать();

// Задаем собственный текст запроса к базе данных
ТекстЗапроса = 
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
|   ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
|   ТоварыНаСкладахОстатки.Склад КАК Склад,
|   ТоварыНаСкладахОстатки.КоличествоОстаток КАК КоличествоОстаток
|ИЗ
|   РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, ) КАК ТоварыНаСкладахОстатки";

ОтчетСозданный.ПостроительОтчета.Текст = ТекстЗапроса;

// Инициализируем настройки построителя на основании нового запроса
ОтчетСозданный.УстановитьНачальныеНастройки(Истина);

// Передаем параметры в запрос построителя
ОтчетСозданный.ПостроительОтчета.Параметры.Вставить("Период", ТекущаяДата());

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

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

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

Резюме

Мы подробно изучили различные способы программного управления Универсальным отчетом в среде 1С на обычных формах. Теперь в зависимости от бизнес-требований вы сможете гибко выбирать наиболее производительный инструмент: выгружать чистые таблицы значений напрямую через ПолучитьРезультат(), генерировать красиво оформленные файлы отчетов с помощью СформироватьОтчет(), либо производить быструю конвертацию экранных форм через ОписаниеИсточникаДанных.

← На главную