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

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

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

В этой статье мы подробно разберем по шагам, почему возникает популярная ошибка «Не поддерживается вывод таблиц и диаграмм в универсальную коллекцию значений», как её правильно исправить программным путем, а также как корректно получить объект внешнего отчета из справочника БСП «Дополнительные отчеты и обработки».

Выясняем причину ошибки генерации макета

Рассмотрим типовой сценарий. Разработчик пытается инициализировать отчет, загрузить настройки одного из вариантов и выполнить компоновку с использованием объекта ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений. Код выглядит следующим образом:


КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(ОтчетСостояниеШтатногоРасписания.СхемаКомпоновкиДанных, НастройкиОтчета,,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));

При выполнении этого фрагмента система аварийно завершает работу с сообщением об ошибке компоновки макета. Проанализируем причину такого поведения платформы.

Процессор вывода СКД при использовании генератора макета для коллекции значений имеет жесткое ограничение. Он не умеет обрабатывать сложные структуры настроек, к которым относятся:

  1. Таблицы (кросс-таблицы): структуры с двумерным выводом данных (строки и колонки).
  2. Диаграммы: графическое представление информации.
  3. Вложенные отчеты: отчеты внутри других отчетов.

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

Решение проблемы: программное «выпрямление» структуры настроек

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

Добавим в процедуру обработки отчета следующий блок кода:


// 1. Очищаем существующую структуру (удаляем таблицы, диаграммы и сложные иерархические группировки)
НастройкиОтчета.Структура.Очистить();

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

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

ПорядокГруппировки = ГруппировкаДетальныеЗаписи.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных"));
ПорядокГруппировки.Использование = Истина;

Важные нюансы, которые следует учитывать при выгрузке в таблицу значений:

Как получить объект внешнего отчета из справочника БСП

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

В БСП предусмотрен готовый программный интерфейс, позволяющий быстро получить полноценный объект внешнего отчета на сервере по его ссылке:


// Получаем ссылку на элемент справочника дополнительных отчетов
СсылкаНаДопОтчет = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию("Состояние штатного расписания");

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

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

Полный пример реализации получения данных

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


Процедура ПолучитьДанныеОтчетаВТаблицу() Экспорт

    // Шаг 1. Получаем объект внешнего отчета из дополнительных отчетов БСП
    СсылкаНаДопОтчет = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию("Состояние штатного расписания");
    
    Если Не ЗначениеЗаполнено(СсылкаНаДопОтчет) Тогда
        ВызватьИсключение "Не найден дополнительный отчет 'Состояние штатного расписания'!";
    КонецЕсли;
    
    // Получаем объект внешнего отчета на сервере
    ОтчетОбъект = ДополнительныеОтчетыИОбработки.ОбъектВнешнейОбработки(СсылкаНаДопОтчет);
    
    // Шаг 2. Загружаем настройки выбранного варианта
    ВариантНастроек = ОтчетОбъект.СхемаКомпоновкиДанных.ВариантыНастроек.ЗаполненностьШтатногоРасписания;
    ОтчетОбъект.КомпоновщикНастроек.ЗагрузитьНастройки(ВариантНастроек.Настройки);
    
    НастройкиОтчета = ОтчетОбъект.КомпоновщикНастроек.ПолучитьНастройки();
    
    // Шаг 3. Заполняем параметры данных
    ПараметрДата = НастройкиОтчета.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ДатаАктуальности"));
    Если ПараметрДата <> Неопределено Тогда
        ПараметрДата.Значение = ТекущаяДата();
        ПараметрДата.Использование = Истина;
    КонецЕсли;
    
    // Шаг 4. Преобразуем структуру отчета в детальные записи
    НастройкиОтчета.Структура.Очистить();
    
    ГруппировкаДетальныеЗаписи = НастройкиОтчета.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
    ГруппировкаДетальныеЗаписи.Использование = Истина;
    
    ВыбранноеПоле = ГруппировкаДетальныеЗаписи.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
    ВыбранноеПоле.Использование = Истина;
    
    ПорядокГруппировки = ГруппировкаДетальныеЗаписи.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных"));
    ПорядокГруппировки.Использование = Истина;
    
    // Шаг 5. Компонуем макет для коллекции значений
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(
        ОтчетОбъект.SхемаКомпоновкиДанных, 
        НастройкиОтчета, 
        , 
        , 
        Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений")
    );
    
    // Инициализируем процессор компоновки
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , , Истина);
    
    // Выводим результат компоновки в Таблицу Значений
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
    РезультатТаблица = Новый ТаблицаЗначений;
    
    ПроцессорВывода.УстановитьОбъект(РезультатТаблица);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки, Истина);
    
    // Теперь переменная 'РезультатТаблица' содержит плоскую таблицу с данными отчета
    ЗначениеВРеквизитФормы(РезультатТаблица, "ТаблицаРезультатНаФорме");

КонецПроцедуры

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

← На главную