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

Публикация № 1005563

Разработка - Практика программирования

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

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

Недавно получил задачу от заказчика вывести отчет - классификацию покупателей по количеству покупок за последние 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", ТЗ);
	
	//Макет компоновки 
	КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
	МакетКомпоновки = КомпоновщикМакета.Выполнить(ЭтотОбъект.СхемаКомпоновкиДанных, ЭтотОбъект.КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки);
	
	//Компоновка данных 
	ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
	ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки);
	
	//Вывод результата 
	ДокументРезультат.Очистить();
	ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
	ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
	ПроцессорВывода.Вывести(ПроцессорКомпоновки);	
	
КонецПроцедуры

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

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

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

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

29

См. также

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. German_Tagil 6 18.02.19 05:38 Сейчас в теме
2. SanchoD 157 18.02.19 15:56 Сейчас в теме
Сортировка нескольких колонок в настройках СКД нормально отработает или надо в модуле сортировать?
Как минимум, хорошо бы в алфавитном порядке всех клиентов вывести. Или по количеству покупок (что продажникам более интересно).
4. srub 54 18.02.19 16:13 Сейчас в теме
(2)
Да, Вы правы. В отчете для заказчика я отсортировал данные по покупателям по количеству закупок и добавил сумму на которую закупился покупатель за период 3 месяца. Я сейчас внесу правки в текст публикации
3. awk 692 18.02.19 16:11 Сейчас в теме
А что мешало перенумеровать данные трех запросов и объединить их по номеру?
dabu-dabu; itriot11; +2 Ответить
5. srub 54 18.02.19 16:16 Сейчас в теме
(3)
Ничего не мешало, но я подумал что так будет нагляднее
6. srub 54 19.02.19 09:30 Сейчас в теме
(3)
Озаботился тем как можно пронумеровать строки в запросах. Нарыл такую статью https://kb.mista.ru/article.php?id=703 Вы это имели в виду?
7. awk 692 19.02.19 10:14 Сейчас в теме
(6) Да... Есть много фишек которые можно с запросами вытворять. Например выводить нарастающий итог и т.п.
8. srub 54 19.02.19 10:31 Сейчас в теме
(7)
Попробовал, вроде получилось, но у меня обрезает количество строк самым меньшим количеством строк из трех таблиц, может я что не так соеденил? Можно конечно сделать левым соединение НеПокупатель, потому как я знаю что там в тестовой базе больше всего записей, а в общем случае как?

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

	Настройки = КомпоновщикНастроек.ПолучитьНастройки();
	ДатаОтсчета = Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ДатаОтсчета")).Значение.Дата;
	
	Запрос.УстановитьПараметр("Дата", ДатаОтсчета);
	
	Результат = Запрос.Выполнить().Выгрузить();
 
Показать
9. awk 692 19.02.19 11:10 Сейчас в теме
(8) Тут полное нужно соединение. Номер через isnull(isnull(A,B),C). С левым соединением надо знать заранее в какой таблице номеров больше.
10. srub 54 19.02.19 11:26 Сейчас в теме
(9)
Спасибо понял. Все получилось. Возьму себе на заметку
Оставьте свое сообщение