Программная обработка данных отчета, полученных с помощью запроса, с выводом измененных данных в СКД






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

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

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)


СтандартнаяОбработка = Ложь;

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Партнеры.Ссылка КАК Ссылка,
| РеализацияТоваровУслугТовары.Сумма КАК СуммаПокупок,
| РеализацияТоваровУслугТовары.Ссылка КАК КоличествоПокупок,
| РеализацияТоваровУслугТовары.Ссылка.Дата КАК Дата
|ПОМЕСТИТЬ Покупатели
|ИЗ
| Справочник.Партнеры КАК Партнеры
|  ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
|  ПО Партнеры.Ссылка = РеализацияТоваровУслугТовары.Ссылка.Партнер
|ГДЕ
| Партнеры.Клиент = ИСТИНА
| И РеализацияТоваровУслугТовары.Ссылка.Проведен = ИСТИНА
| И РеализацияТоваровУслугТовары.Ссылка.Дата МЕЖДУ ДОБАВИТЬКДАТЕ(&Дата, МЕСЯЦ, -3) И &Дата
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Покупатели.Ссылка КАК Ссылка,
| СУММА(Покупатели.СуммаПокупок) КАК СуммаПокупокН,
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Покупатели.КоличествоПокупок) КАК КоличествоПокупокН
|ПОМЕСТИТЬ НеРегПок
|ИЗ
| Покупатели КАК Покупатели
|
|СГРУППИРОВАТЬ ПО
| Покупатели.Ссылка
|
|ИМЕЮЩИЕ
| (КОЛИЧЕСТВО(РАЗЛИЧНЫЕ МЕСЯЦ(Покупатели.Дата)) = 2
|  ИЛИ КОЛИЧЕСТВО(РАЗЛИЧНЫЕ МЕСЯЦ(Покупатели.Дата)) = 1) И
| НЕ КОЛИЧЕСТВО(РАЗЛИЧНЫЕ МЕСЯЦ(Покупатели.Дата)) = 3
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Покупатели.Ссылка КАК Ссылка,
| СУММА(Покупатели.СуммаПокупок) КАК СуммаПокупокР,
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Покупатели.КоличествоПокупок) КАК КоличествоПокупокР
|ПОМЕСТИТЬ РегПок
|ИЗ
| Покупатели КАК Покупатели
|
|СГРУППИРОВАТЬ ПО
| Покупатели.Ссылка
|
|ИМЕЮЩИЕ
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ МЕСЯЦ(Покупатели.Дата)) = 3
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| Партнеры.Ссылка КАК НеПокупатели
|ИЗ
| Справочник.Партнеры КАК Партнеры
|ГДЕ
| Партнеры.Клиент = ИСТИНА
| И НЕ Партнеры.Ссылка В
|    (ВЫБРАТЬ
|     НеРегПок.Ссылка КАК Ссылка
|    ИЗ
|     НеРегПок КАК НеРегПок)
| И НЕ Партнеры.Ссылка В
|    (ВЫБРАТЬ
|     РегПок.Ссылка КАК Ссылка
|    ИЗ
|     РегПок КАК РегПок)
| И Партнеры.Клиент = ИСТИНА
|
|УПОРЯДОЧИТЬ ПО
| НеПокупатели
|АВТОУПОРЯДОЧИВАНИЕ
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| НеРегПок.Ссылка КАК НеРегПокупатели,
| НеРегПок.КоличествоПокупокН КАК КоличествоПокупокН,
| НеРегПок.СуммаПокупокН КАК СуммаПокупокН
|ИЗ
| НеРегПок КАК НеРегПок
|
|УПОРЯДОЧИТЬ ПО
| КоличествоПокупокН
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| РегПок.Ссылка КАК РегПокупатели,
| РегПок.КоличествоПокупокР КАК КоличествоПокупокР,
| РегПок.СуммаПокупокР КАК СуммаПокупокР
|ИЗ
| РегПок КАК РегПок
|
|УПОРЯДОЧИТЬ ПО
| КоличествоПокупокР";


Настройки = КомпоновщикНастроек.ПолучитьНастройки();
ДатаОтсчета = Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ДатаОтсчета")).Значение.Дата;

Запрос.УстановитьПараметр("Дата", ДатаОтсчета);

МассивРезультатов = Запрос.ВыполнитьПакет();

//Не Покупатели
Выборка = МассивРезультатов[3].Выгрузить();
МассивНП = Выборка.ВыгрузитьКолонку(0);

//Не регулярные покупатели
Выборка = МассивРезультатов[4].Выгрузить();
МассивНР = Выборка.ВыгрузитьКолонку(0);
МассивНРК = Выборка.ВыгрузитьКолонку(1);
МассивНРС = Выборка.ВыгрузитьКолонку(2);

//Регулярные покупатели
Выборка = МассивРезультатов[5].Выгрузить();
МассивРП = Выборка.ВыгрузитьКолонку(0);
МассивРПК = Выборка.ВыгрузитьКолонку(1);
МассивРПС = Выборка.ВыгрузитьКолонку(2);

//Определим массив с наибольшим количеством строк
НаибольшееКол = МАКС(МассивНП.Вграница(), МАКС(МассивНР.Вграница(), МассивРП.Вграница()));

ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("РегулярныеПокупатели", Новый ОписаниеТипов("СправочникСсылка.Партнеры"));
ТЗ.Колонки.Добавить("КоличествоПокупокР", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10,0)));
ТЗ.Колонки.Добавить("СуммаПокупокР", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10,2)));
ТЗ.Колонки.Добавить("НеРегулярныеПокупатели", Новый ОписаниеТипов("СправочникСсылка.Партнеры"));
ТЗ.Колонки.Добавить("КоличествоПокупокН", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10,0)));
ТЗ.Колонки.Добавить("СуммаПокупокН", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10,2)));
ТЗ.Колонки.Добавить("НеПокупатели", Новый   ОписаниеТипов("СправочникСсылка.Партнеры"));

//Создадим пустые строки ТЗ
Для Инд = 0 По НаибольшееКол Цикл
ТЗ.Добавить();
КонецЦикла;

//Загрузим массивы в колонки
ТЗ.ЗагрузитьКолонку(МассивРП,"РегулярныеПокупатели");
ТЗ.ЗагрузитьКолонку(МассивРПК,"КоличествоПокупокР");
ТЗ.ЗагрузитьКолонку(МассивРПС,"СуммаПокупокР");
ТЗ.ЗагрузитьКолонку(МассивНР,"НеРегулярныеПокупатели");
ТЗ.ЗагрузитьКолонку(МассивНРК,"КоличествоПокупокН");
ТЗ.ЗагрузитьКолонку(МассивНРС,"СуммаПокупокН");
ТЗ.ЗагрузитьКолонку(МассивНП,"НеПокупатели");


//Связь между таблицей значений и именами в СКД
ВнешниеНаборыДанных = Новый Структура;
ВнешниеНаборыДанных.Вставить("НаборДанных1", ТЗ);

//Макет компоновки
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(ЭтотОбъект.СхемаКомпоновкиДанных, ЭтотОбъект.КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки);

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

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

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

Далее нажмите кнопочку ОсновнаяСхемаКомпоновкиДанных добавить Набор данных — Объект и заполнить согласно структуре своего отчета не забывая указывать тип значения  Установить Параметры, в моем случае это Дата, 

и заполнить вкладку Настройки

и ваш отчет на СКД с программной обработкой данных готов.

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

10 Comments

  1. German_Tagil

    запомнил

    Reply
  2. SanchoD

    Сортировка нескольких колонок в настройках СКД нормально отработает или надо в модуле сортировать?

    Как минимум, хорошо бы в алфавитном порядке всех клиентов вывести. Или по количеству покупок (что продажникам более интересно).

    Reply
  3. awk

    А что мешало перенумеровать данные трех запросов и объединить их по номеру?

    Reply
  4. srub

    (2)

    Да, Вы правы. В отчете для заказчика я отсортировал данные по покупателям по количеству закупок и добавил сумму на которую закупился покупатель за период 3 месяца. Я сейчас внесу правки в текст публикации

    Reply
  5. srub

    (3)

    Ничего не мешало, но я подумал что так будет нагляднее

    Reply
  6. srub

    (3)

    Озаботился тем как можно пронумеровать строки в запросах. Нарыл такую статью https://kb.mista.ru/article.php?id=703 Вы это имели в виду?

    Reply
  7. awk

    (6) Да… Есть много фишек которые можно с запросами вытворять. Например выводить нарастающий итог и т.п.

    Reply
  8. srub
    Reply
  9. awk

    (8) Тут полное нужно соединение. Номер через isnull(isnull(A,B),C). С левым соединением надо знать заранее в какой таблице номеров больше.

    Reply
  10. srub

    (9)

    Спасибо понял. Все получилось. Возьму себе на заметку

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *