Недавно получил задачу от заказчика вывести отчет — классификацию покупателей по количеству покупок за последние 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", ТЗ);
//Макет компоновки
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(ЭтотОбъект.СхемаКомпоновкиДанных, ЭтотОбъект.КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки);
//Компоновка данных
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки);
//Вывод результата
ДокументРезультат.Очистить();
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры
Далее нажмите кнопочку ОсновнаяСхемаКомпоновкиДанных добавить Набор данных — Объект и заполнить согласно структуре своего отчета не забывая указывать тип значения Установить Параметры, в моем случае это Дата,
и заполнить вкладку Настройки
и ваш отчет на СКД с программной обработкой данных готов.
Для многих это не будет новостью, но кому-то, возможно, реально поможет сэкономить время.
запомнил
Сортировка нескольких колонок в настройках СКД нормально отработает или надо в модуле сортировать?
Как минимум, хорошо бы в алфавитном порядке всех клиентов вывести. Или по количеству покупок (что продажникам более интересно).
А что мешало перенумеровать данные трех запросов и объединить их по номеру?
(2)
Да, Вы правы. В отчете для заказчика я отсортировал данные по покупателям по количеству закупок и добавил сумму на которую закупился покупатель за период 3 месяца. Я сейчас внесу правки в текст публикации
(3)
Ничего не мешало, но я подумал что так будет нагляднее
(3)
https://kb.mista.ru/article.php?id=703 Вы это имели в виду?
Озаботился тем как можно пронумеровать строки в запросах. Нарыл такую статью
(6) Да… Есть много фишек которые можно с запросами вытворять. Например выводить нарастающий итог и т.п.
(8) Тут полное нужно соединение. Номер через isnull(isnull(A,B),C). С левым соединением надо знать заранее в какой таблице номеров больше.
(9)
Спасибо понял. Все получилось. Возьму себе на заметку