Почти динамическая группировка по периоду в СКД

30.01.15

Разработка - СКД

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

 

На самом деле все мы помним замечательный Универсальный отчет, который легким движением руки позволял пользователю самому выбрать период развертки. В СКД пользователь тоже может это сделать сам, но для этого ему надо изменять вариант отчета, а, к сожалению, пользователи редко хотят и умеют это делать. Да и всё равно для этого необходимо создать список необходимых полей периодов.

 

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

Покажу 2 варианта, но существуют, конечно же, и другие. Можно, к примеру, в процедуре

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) 	
// тут можно проанализировать какие-то параметры 
// и в структуре СКД сделать необходимые перестановки, но 
// это не true way потому что не интересно. КонецПроцедуры



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


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

Создание параметра

Вариант 1.


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

 

ВЫБРАТЬ

//какие-то поля,

ВЫБОР
    КОГДА &Периодичность = 1
        ТОГДА НачалоПериода(Дата, МЕСЯЦ)
    КОГДА &Периодичность = 2
        ТОГДА НачалоПериода(Дата, КВАРТАЛ)
    КОГДА &Периодичность = 3
        ТОГДА НачалоПериода(Дата, ПОЛУГОДИЕ)
    КОГДА &Периодичность = 4
        ТОГДА НачалоПериода(Дата, ГОД)
КОНЕЦ КАК Период

 


 

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

 Выражение упорядочивания

 

ВЫБОР 
    КОГДА &Периодичность = 1  
        ТОГДА Формат(Дата, "ДФ='ММММ гггг ""г.""' ") 
    КОГДА &Периодичность = 2  
        ТОГДА Формат(Дата,"ДФ='к ""квартал"" гггг ""г.""'" ) 
    КОГДА &Периодичность = 3 
        ТОГДА 
        ВЫБОР 
            КОГДА Квартал(Дата) < 3 
                ТОГДА "1" ИНАЧЕ "2"
        КОНЕЦ + Формат(Дата, "ДФ=' ""полугодие"" гггг ""г."" '")
    КОГДА &Периодичность = 4 
        ТОГДА Формат(Дата,"ДФ='гггг ""г.""'")
КОНЕЦ

Естественно, можно настроить формат так, как хотите. Можно и не настраивать.

 

Осталось только добавить наше поле в структуру варианта и вынести параметр Периодичность в быстрые настройки, для удобства.

Группировка

В общем-то, всё, почти динамическая группировка готова. Почему почти? Ну мы же должны заранее задать и описать необходимые периоды!

 

Вариант 2.

Этот вариант очень похож на первый, я тут просто покажу пару возможностей СКД. Тут мы, вместо одного поля Период, сделаем несколько полей. Месяц, Квартал, Полугодие, Год и т.д.

 

В запросе опишем эти поля вот таким образом

ВЫБОР
    КОГДА &Периодичность = 1
        ТОГДА НАЧАЛОПЕРИОДА(ВТ_Данные.Месяц, МЕСЯЦ)
    ИНАЧЕ NULL
КОНЕЦ КАК Месяц,
ВЫБОР
    КОГДА &Периодичность = 2
        ТОГДА НАЧАЛОПЕРИОДА(ВТ_Данные.Месяц, Квартал)
    ИНАЧЕ NULL
КОНЕЦ КАК Квартал,
ВЫБОР
    КОГДА &Периодичность = 3
        ТОГДА НАЧАЛОПЕРИОДА(ВТ_Данные.Месяц, Полугодие)
    ИНАЧЕ NULL
КОНЕЦ КАК Полугодие,
ВЫБОР
    КОГДА &Периодичность = 4
        ТОГДА НАЧАЛОПЕРИОДА(ВТ_Данные.Месяц, Год)
    ИНАЧЕ NULL
КОНЕЦ КАК Год,

 

NULL обязателен, чтобы использовать одну из настроек СКД - "Игнорировать NULL". Если не хотите использовать NULL, то никто не мешает для каждой из 4 группировок создать свой собственный отбор на параметр Периодичность. Я это описывать не буду, думаю и так всё очевидно.

Настройка поля

 

И создаем 4 группировки с этими полями.

 Мы так описали поля, что все, кроме одного периода, нужного нам, будут иметь значение NULL, и из-за настройки Игнорировать NULL они будут просто, внезапно, проигнорированы.

 Результат запроса

Так что в СКД избавляться от NULL нужно с умом :) иногда оно бывает полезно.

 

 

На самом деле такой подход работает далеко не только для периода. Я подобным подходом пользуюсь в разных отчетах довольно часто

СКД Периоды

См. также

SALE! 15%

Инструментарий разработчика Роли и права Запросы СКД Программист Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

10000 руб.

02.09.2020    159433    872    399    

861

Запросы СКД Программист Стажер Система компоновки данных Россия Бесплатно (free)

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

15.05.2024    8684    implecs_team    6    

47

Инструментарий разработчика СКД Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

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

3 стартмани

05.02.2024    6996    56    obmailok    21    

79

Запросы СКД Программист Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Есть список полей в виде текста, или запрос - закидываем в набор СКД.

1 стартмани

31.01.2024    3148    5    Yashazz    1    

34

СКД WEB-интеграция Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Долгое время поддерживаю web-портал, в котором появилась необходимость создавать отчеты. Просмотрев различные фреймворки на js, я решил сделать свое решение, которое позволяло бы быстро разрабатывать и добавлять новые отчеты на web-портал.

2 стартмани

11.12.2023    10804    23    John_d    25    

124

СКД Программист Платформа 1С v8.3 Система компоновки данных Конфигурации 1cv8 Бесплатно (free)

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

05.12.2023    8017    PROSTO-1C    15    

68
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Yashazz 4790 30.01.15 16:27 Сейчас в теме
Я бы это делал вычисляемыми полями...
2. slazzy 42 30.01.15 16:42 Сейчас в теме
(1) Yashazz, можно и полями, собственно какая разница? :)

3. echo77 1906 31.01.15 14:23 Сейчас в теме
4. Lyns_owner 356 01.02.15 22:41 Сейчас в теме
Я уже писал подобную статью, а почитав комментарии к ней, можно написать отличный отчет - http://infostart.ru/public/125216/

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

	
"ВЫБРАТЬ
	|	ВирутальнаяТаблица.Поле1 КАК Поле1,
	|	ВирутальнаяТаблица.Поле2 КАК Поле2,
	|	НАЧАЛОПЕРИОДА(ВирутальнаяТаблица.Период, " + Периодичность + ") КАК Период,
	|ИЗ
	|	РегистрНакопления.ВирутальнаяТаблица.Обороты(&НачалоПериода, &КонецПериода, " + Периодичность + ", ) КАК ВирутальнаяТаблицаОбороты"
7. slazzy 42 02.02.15 09:57 Сейчас в теме
(4) Lyns_owner, спасибо за ссылку, Вашу статью я не нашел при поиске. По поводу
Самым правильным вариантом считаю составление текста запроса с учетом переданного параметра (задавать периодичность виртуальной таблицы) с последующей передачей внешнего набора данных (таблицы) в макет СКД.

У меня только один вопрос. На каком основании Вы считаете, что этот метод "самый правильный"? Я вот так не считаю. К тому же далеко не всегда у нас виртуальная таблица оборотов используется в отчете.

(6) zqzq, да можно, но всё равно это не так удобно, однако как вариант почему нет. Я же написал - это один из вариантов. Мне удобнее делать так, кому-то удобнее иначе :)
8. Lyns_owner 356 02.02.15 14:02 Сейчас в теме
(7) Не считаете - обоснуйте, почему. Правильный - значит быстродейственный. При его использовании нет необходимости вычисления периода для каждой строчки отчета.
К тому же далеко не всегда у нас виртуальная таблица оборотов используется в отчете.

Я стесняюсь спросить, ЧТО вы еще собираетесь в отчете с вертикальной группировкой по периоду? Регистр сведений? Может вообще дату документов? Опять же возвращаемся к разговору про быстродействие.
9. slazzy 42 02.02.15 15:54 Сейчас в теме
(8) Lyns_owner,
Правильный - значит быстродейственный. При его использовании нет необходимости вычисления периода для каждой строчки отчета.

зато есть необходимость менять текст запроса, создавать ТЗ, загружать его в СКД и прочее. А посчитать case для строчки дело не сложное, к тому же в моем примере идет сравнение чисел, что в общем-то вряд ли сильно затруднит обработку.

Но я так же могу поспорить и с фразой "правильный - значит быстродейственный." Мы пишем не на С++ и 1С сама по себе довольно медлительна и много где теряет производительность. Вообще код в 1С должен соблюдать баланс между скоростью работы и скоростью восприятия этого кода другим программистом. По моему сугубо личному мнению все эти обработки при компановке, передача ТЗ как внешний источник и прочие извращения это от криворукости, когда человек не может в СКД сделать нормальный запрос. И анализировать это разбирая процедуры, которые наваял автор бывает довольно проблемно. И если вы ради вычисления одного поля будете всё переносить в модуль, то...ну даже не знаю. Бывают ситуации, когда без этого не обойтись, но они бывают редко.

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

Не считаете - обоснуйте, почему.

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


Я только что специально протестировал этот механизм с использованием планировщика(только сам запрос), чтобы я ни делал выше 0% общая стоимость выполнения comptute scalar не превышала, там что-то в районе 0.000000014 общая стоимость. Поэтому истории про то, что тяжело рассчитать case для каждой строчки несколько надуманы.
Кстати что интересно в SQL запрос попадает не весь case а только верный вариант, не знаю с чем это связано пока.


Я стесняюсь спросить, ЧТО вы еще собираетесь в отчете с вертикальной группировкой по периоду? Регистр сведений? Может вообще дату документов? Опять же возвращаемся к разговору про быстродействие.

Стесняться не надо, в этом нет необходимости. Дело в том, что мой метод универсален и конкретно я его придумал когда делал разворот по датам, которые брались из документа(но не дата документа) довольно сложная аналитическая самописная конфа для финансового планирования и ради одного отчета делать регистр начальство не посчитало нужным. Но в целом да, это своего рода обороты. Но дело ведь не в этом, правда? :) моя маленькая заметка находится в разделе "практика программирования" и она довольно универсальна, плюс раскрывает некоторые довольно интересные методы работы с СКД.
Я вообще не понимаю откуда этот спор. Я просто предложил ещё один метод(о чем и написал) как это сделать. На мой личный взгляд это самый красивый способ, хотя способов конечно много. Плюс, я уверен, он работает с не худшей производительностью, чем предложенный Вами способ.
10. Lyns_owner 356 03.02.15 00:38 Сейчас в теме
(9)
Мы пишем не на С++ и 1С сама по себе довольно медлительна и много где теряет производительность

А вам сказать, благодаря кому она такая медленная? или Сами догадаетесь? А тестировали вы на каких данных? Сколько строк в результирующем запросе? 10?
Программист пишет не так, чтобы это было легко сделать (очень близко к определению понятия "говнокод"), а так, чтобы это работа правильно и максимально быстро.
Да извольте анализировать процедуры, написанные автором. Все правильное реализуется непросто, а что реализуется просто - то поделка школьника. Возьмите к примеру запросы вычисления страховых взносов в ЗУПе - их тупо листать устанешь, не то что разбирать. А на первый взгляд, там сложного ничего нет - есть база и есть процент))

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

Но дело ведь не в этом, правда? :)

Да, дело не в этом. Дело в том, что ваша статья в том или ином виде уже больше года присутствует на Инфостарте. А еще ваши ответы характеризуют вас как некомпетентного специалиста.
11. slazzy 42 03.02.15 12:19 Сейчас в теме
(10),
А еще ваши ответы характеризуют вас как некомпетентного специалиста.

Пойду поплачу.

А теперь по делу. Сделал регистр сведений, добавил туда пару полей и одно из полей Дата, добавил в него 510к строк. Судя по плану запроса вычисление периода тратит 1% от общего времени(ориентировочно)

Такие дела.

Да и, к слову, в 1С есть стандарты разработки, которые ставят качество восприятия кода на одну ступень с его быстродействием, за редчайшим исключением вроде процедур проведения, где каждая секунда важна.
И если по Вашему стоит из-за любого чиха обработку переносить в модуль, вместо СКД и считаете это правильным, то мне надо Вас огорчить. Сказать почему? Ну например СКД динамически формирует запрос и отборы в СКД автоматически переносятся в запрос тоже... Может случиться такая ситуация, что пользователю будет нужна одна строка, а вы создадите свою таблицу из миллиона записей в модуле и СКД всё равно отберет одну строку....поспорим о производительности? Или будете все допустимые отборы выносить на форму и обрабатывать в своем запросе? СКД автоматически работает с характеристиками. Но главная причина спора и производительность это тема тоже сложная. Я например абсолютно убежден, что сделать запрос на миллион строк и выгрузить его в ТЗ, а потом передать как внешний источник данных в СКД - нереально медленная операция, тут потери производительности на создание ТЗ просто громадны и они даже близко не сопоставимы с мизерными потерями на расчет периода в строке.
Да и просто анализировать единый запрос в СКД куда правильнее чем раскидывать код по модулям без причин.


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

(10), я надеюсь на этом мы закончим нашу беседу, мне она не очень интересна, извините уж :)
12. alest 04.02.15 16:58 Сейчас в теме
Ну например СКД динамически формирует запрос и отборы в СКД автоматически переносятся в запрос тоже...
Ну а зачем трюк с нуллом? Выбрал в запросе сразу поля, а скд откинет лишнее. Она даже соединения таблиц убирает, если поля не выбраны в настройках.
Прошу прощения, не так понял, вы не хотели заморачиваться с выбором вариантов...

(10) Lyns_owner, я тоже считаю, что ваш вариант с программным составлением явно не для СКД. Может вы вообще все за СКД сделаете и отдадите ей только те поля в запросе, которые в конкретном варианте настроек будут, да еще и отборы сразу наложите?
13. slazzy 42 04.02.15 17:20 Сейчас в теме
(12) alest,
Ну а зачем трюк с нуллом? Выбрал в запросе сразу поля, а скд откинет лишнее. Она даже соединения таблиц убирает, если поля не выбраны в настройках.

Хороший вопрос :) нет тут дело немного в другом, в моем примере я именно "выбираю все поля", но те, где NULL, автоматически отсекаются. То есть если бы там не было NULL, они бы вывелись.
Вы же говорите про другое, то есть я гипотетически могу создать 4 поля(для 4-х периодов) и выводить только одно из них, а остальные сами отсекутся. Да, это так, но для этого надо вручную менять структуру отчета, чтобы включить только нужные поля. Я же хотел именно чтобы к структуре отчета пользователь даже не подходил. Но, справедливости ради, это и правда довольно нетипичный метод и в данном случае он излишне сложный :) я его показал просто как пример работы с NULL.

Очень похожий способ используется в типовых конфигурациях, когда идет работа с таблицей ОстаткиИОбороты и надо вывести регистратор.
5. Поручик 4692 02.02.15 00:46 Сейчас в теме
Очень интересно. Не забыть попробовать переделать один отчет. Пытался несколько раз, но ничего путного не выходило
6. zqzq 25 02.02.15 09:00 Сейчас в теме
В СКД пользователь тоже может это сделать сам, но для этого ему надо изменять вариант отчета
В настройках СКД можно включить группировки (строк, колонок, подчинённых строк) в быстрые пользовательские настройки. Тогда пользователь хоть период, хоть 2 периода, хоть любую другую группировку сможет убрать/добавить в отчет без изменения варианта. Без всякого программирования и порчи текста запроса.
14. dabu-dabu 307 03.03.15 13:28 Сейчас в теме
Если используется виртуальная таблица Обороты или ОстаткиИОбороты, то можно просто поставить параметр компоновки, например так:
ВЫБРАТЬ
	ПродажиОбороты.Период,
	ПродажиОбороты.Контрагент,
	ПродажиОбороты.СтоимостьОборот
ИЗ
	РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, ДЕНЬ{(&Периодичность)}, ) КАК ПродажиОбороты
15. slazzy 42 03.03.15 14:10 Сейчас в теме
(14) dabu-dabu, а Вы не могли бы поподробнее показать? Дело в том, что я попробовал так сделать. Передаю параметр, например, "Месяц", а всё равно период берется как день, что и логично в общем-то...у меня не получилось сделать корректный разворот по динамическому периоду
16. dabu-dabu 307 03.03.15 18:09 Сейчас в теме
(15) Тип формируемого параметра не надо менять, либо установить тип число. Если я не ошибаюсь, значения следующие: 0 - период, 1 - запись, 2 - регистратор, 3 - секунда, 4 - минута и т.д.
Список доступных значений, при этом, устанавливать не обязательно. СКД как-то сам понимает, что это периодичность.
17. Ibrogim 1327 12.03.15 13:38 Сейчас в теме
Интересен второй метод, автору +
Однако к каждому измерению(квартал,месяц, ... ) выводится Итог, а если в "других настройках" для измерений установить Расположение итогов = нет, то почему то не выводится ресурс...
Возможно Я где то напутал конечно...
18. taasha25 13 13.12.18 15:56 Сейчас в теме
19. Girl_Tat 2 30.04.22 21:00 Сейчас в теме
Оставьте свое сообщение