Как программно получить и обработать данные из отчета на СКД?

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

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

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

Способ 1: Прямое формирование результата в ТаблицуЗначений

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

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

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

Сначала в модуле формы отчета разместим код обработчика команды (нашей кнопки):


// Код в модуле формы отчета
&НаКлиенте
Процедура ОбработатьРезультат(Команда)
    ОбработатьРезультатНаСервере();
КонецПроцедуры

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

Теперь реализуем саму функцию ПолучениеРезультатаСКД в модуле объекта отчета. Именно здесь и происходит вся магия компоновки.


// Код в модуле объекта отчета
Функция ПолучениеРезультатаСКД() Экспорт

    // 1. Создаем компоновщик макета
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;

    // 2. Выполняем компоновку макета, но с особым генератором.
    // Вместо стандартного генератора макета для табличного документа,
    // мы используем "ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений".
    // Это ключевой момент, который указывает СКД, что результат нужен в виде коллекции.
    МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(
        СхемаКомпоновкиДанных, 
        КомпоновщикНастроек.ПолучитьНастройки(),
        , , 
        Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений")
    );

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

    // 4. Готовим приемник для данных - ТаблицуЗначений
    Таблица = Новый ТаблицаЗначений;

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

    // 6. Выполняем вывод
    ПроцессорВыводаРезультатаКомпоновкиДанных.Вывести(ПроцессорКомпоновкиДанных);
    
    // 7. Возвращаем готовую таблицу
    Возврат Таблица;

КонецФункции

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

Способ 2: Интерактивная обработка выделенных строк через расшифровку

Что если нам не нужны все данные отчета, а только те строки, которые пользователь выделил или на которые кликнул? Для этого в 1С существует мощный механизм — обработка расшифровки. Вместо добавления отдельной кнопки на форму, мы можем встроить нашу логику прямо в контекстное меню отчета или выполнять ее по двойному клику.

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

Разберем по шагам, как это реализовать:

  1. На форме отчета найдите элемент, в который выводится результат (обычно это поле типа ТабличныйДокумент).
  2. В палитре свойств этого элемента перейдите на вкладку "События" и создайте обработчик для события ОбработкаРасшифровки.
  3. В созданном обработчике события мы получаем доступ ко всей информации о ячейке, по которой кликнул пользователь.

Пример кода в обработчике события ОбработкаРасшифровки:


&НаКлиенте
Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)
    
    // Отменяем стандартное действие (например, открытие документа-регистратора)
    СтандартнаяОбработка = Ложь; 
    
    // Получаем данные расшифровки на сервере
    ОбработатьРасшифровкуНаСервере(Расшифровка);
    
КонецПроцедуры

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

С помощью этого механизма можно не только обрабатывать клики, но и добавлять собственные команды в контекстное меню отчета, что делает его по-настоящему интерактивным. Например, можно добавить команду "Создать заказ клиента" прямо в меню, появляющееся по правому клику на строке с контрагентом.

Способ 3: Извлечение запроса и настроек для ручного выполнения

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

Этот подход дает полный контроль над данными на самом раннем этапе.

Алгоритм действий следующий:

  1. Получить итоговые настройки. Пользователь мог добавить в отчет свои отборы, изменить сортировку и т.д. Все эти изменения хранятся в объекте КомпоновщикНастроек.
  2. Сформировать макет компоновки. На основе схемы и настроек мы получаем макет, который содержит в себе готовый текст запроса.
  3. Извлечь текст запроса и параметры. Из макета можно получить текст запроса и значения параметров.
  4. Выполнить запрос. Создать новый объект Запрос, установить его текст и параметры, и выполнить. Результат вы получите в виде ТаблицыЗначений или РезультатаЗапроса.

Как получить пользовательские отборы?

Часто возникает вопрос, как учесть фильтры, которые пользователь установил в отчете интерактивно. Эти данные можно получить из компоновщика настроек:


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

// Теперь можно перебрать коллекцию отборов и проанализировать их
Для Каждого ЭлементОтбора Из ЭлементыОтбора Цикл
    Если НЕ ЭлементОтбора.Использование Тогда
        Продолжить;
    КонецЕсли;
    
    ИмяПоля = ЭлементОтбора.ЛевоеЗначение;
    ВидСравнения = ЭлементОтбора.ВидСравнения;
    ЗначениеОтбора = ЭлементОтбора.ПравоеЗначение;
    
    // Здесь мы можем использовать полученные данные для установки параметров 
    // в нашем собственном объекте "Запрос"
    Сообщить("Установлен отбор по полю '" + ИмяПоля + "'");
КонецЦикла;

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

Для чего использовать событие "ПриКомпоновкеРезультата"?

Иногда упоминается событие отчета ПриКомпоновкеРезультата. Важно понимать его назначение. Это событие срабатывает после того, как СКД уже сформировала результат в виде ТабличногоДокумента, но еще не показала его пользователю.

Оно предназначено в основном для:

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

← На главную