1с скд периодичность в параметрах

Обновлено: 06.07.2024

Использование параметров - периодов в системе компоновки данных

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



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


Для того чтобы введенные значения интерпретировалось в отчете как начало и конец дня следует в запросе использовать функции НачалоПериода() и КонецПериода() .

ВЫБРАТЬ
ПродажиОбороты.Контрагент,
ПродажиОбороты.Номенклатура,
ПродажиОбороты.КоличествоОборот,
ПродажиОбороты.СуммаОборот
ИЗ
РегистрНакопления.Продажи.Обороты(
<(НАЧАЛОПЕРИОДА(&ПериодНачало, ДЕНЬ))>,
<(КОНЕЦПЕРИОДА(&ПериодКонец, ДЕНЬ))>, , ) КАК ПродажиОбороты

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

Использование стандартных периодов

Система компоновки данных позволяет использовать стандартные периоды для указания периода отчета.

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


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

Пользователь будет редактировать параметр в следующем виде:


Для показанного примера в качестве значения параметра ПериодНачала будет использоваться дата 01.01.2019 , а в качестве значения параметра ПериодКонец будет использоваться дата 31.01.2019 .

Реальные значения дат для стандартного периода определяются при исполнении отчета. Таким образом, если выполнять отчет с установленным периодом Этот месяц в январе 2020-го года, то отчет будет исполняться с 01.01.2020 по 31.01.2020 , а если выполнять в феврале 2020-го года, то с 01.02.2020 по 29.02.2020

Заметим, что даты начала и конца стандартного периода также содержат и время. Причем, начальная дата имеет время 00:00:00 , а конечная дата 23:59:59 , таким образом, в запросе не обязательно использовать функции НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА .

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

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

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

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

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

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

Вариант 1.

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

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

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

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

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

Группировка

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

Вариант 2.

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

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

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

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

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


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

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

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

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

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

Electronic Software Distribution

Интеграция 1С с системой Меркурий

Алкогольная декларация

Готовые переносы данных

54-ФЗ

Управление проектом на Инфостарте

Траектория обучения 1С-разработчика

(1) Yashazz, можно и полями, собственно какая разница? :)

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

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

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

(6) zqzq, да можно, но всё равно это не так удобно, однако как вариант почему нет. Я же написал - это один из вариантов. Мне удобнее делать так, кому-то удобнее иначе :)

(7) Не считаете - обоснуйте, почему. Правильный - значит быстродейственный. При его использовании нет необходимости вычисления периода для каждой строчки отчета.
К тому же далеко не всегда у нас виртуальная таблица оборотов используется в отчете.
Я стесняюсь спросить, ЧТО вы еще собираетесь в отчете с вертикальной группировкой по периоду? Регистр сведений? Может вообще дату документов? Опять же возвращаемся к разговору про быстродействие. Правильный - значит быстродейственный. При его использовании нет необходимости вычисления периода для каждой строчки отчета.

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

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

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

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

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

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

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

Разворот по датам, которые брались из документа(но не дата документа) довольно сложная аналитическая самописная конфа для финансового планирования и ради одного отчета делать регистр начальство не посчитало нужным

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


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


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

Такие дела.

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

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

(10), я надеюсь на этом мы закончим нашу беседу, мне она не очень интересна, извините уж :)

Ну например СКД динамически формирует запрос и отборы в СКД автоматически переносятся в запрос тоже.

Ну а зачем трюк с нуллом? Выбрал в запросе сразу поля, а скд откинет лишнее. Она даже соединения таблиц убирает, если поля не выбраны в настройках.
Прошу прощения, не так понял, вы не хотели заморачиваться с выбором вариантов.

(10) Lyns_owner, я тоже считаю, что ваш вариант с программным составлением явно не для СКД. Может вы вообще все за СКД сделаете и отдадите ей только те поля в запросе, которые в конкретном варианте настроек будут, да еще и отборы сразу наложите?

Ну а зачем трюк с нуллом? Выбрал в запросе сразу поля, а скд откинет лишнее. Она даже соединения таблиц убирает, если поля не выбраны в настройках.

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

Очень похожий способ используется в типовых конфигурациях, когда идет работа с таблицей ОстаткиИОбороты и надо вывести регистратор.

Дополнение периодов в системе компоновки данных

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

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

Данные будем получать при помощи следующего запроса:

Для отчета будем использовать следующие настройки:


Т.е. в отчет будем выдавать группировку по периоду и диаграмму группировкой по периоду в сериях.

Если мы будем получать отчет с группировкой по периоду без дополнения, то результат отчета будет выглядеть следующим образом:


Как видно, дни, за которые отсутствовали движения, в отчет не выводятся, что не позволяет визуально отслеживать динамику изменения остатков.

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


Результат отчета с этой настройкой будет выглядеть следующим образом:


В данном результате видно, что остатки выдаются на все дни, даже если в эти дни не было движений.

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

Для демонстрации этой возможности воспользуемся отчетом о продажах, в котором будем использовать следующий запрос:

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

Результат отчета без дополнения будет выглядеть так:

Результат с дополнением по дням без указания интервала будет выглядеть так:

Т.е. дополнение произошло в интервале, дат, которые были получены из набора данных.

Если у поля группировки установить начальную и конечную дату периода следующим образом:


То дополнение по дням произойдет в указанном интервале и результат отчета будет выглядеть так:

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


Если в качестве начальной и/или конечной дат периода используется поле, то дополнение будет осуществляться до даты, полученной из этого поля. Заметим, что в качестве полей, значение которых будет использоваться для указания начальной или конечной даты периода, можно использовать только поля - параметры и поля отчета - владельца (в случае если дополнение происходит во вложенном отчете). Для примера, воспользуемся в качестве начальной даты полем - параметром - начало периода, а в качестве конечной даты - параметром - конец периода. При этом результат будет дополняться в том периоде, который указан в параметрах данных отчета.


Как видно в данном примере, дополнение произошло в интервале, указанном в параметрах данных.

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


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

Рассмотрим следующую настройку:


В отчет будут выдаваться периоды, сгруппированные по месяцам.

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

При дополнении в периоде 01.01.2002 - 31.03.2002 результат может выглядеть следующим образом:

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

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

Результат будет выглядеть так:

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

Дополнение периодов в системе компоновки данных

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

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

Данные будем получать при помощи следующего запроса:

Для отчета будем использовать следующие настройки:


Т.е. в отчет будем выдавать группировку по периоду и диаграмму группировкой по периоду в сериях.

Если мы будем получать отчет с группировкой по периоду без дополнения, то результат отчета будет выглядеть следующим образом:


Как видно, дни, за которые отсутствовали движения, в отчет не выводятся, что не позволяет визуально отслеживать динамику изменения остатков.

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


Результат отчета с этой настройкой будет выглядеть следующим образом:


В данном результате видно, что остатки выдаются на все дни, даже если в эти дни не было движений.

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

Для демонстрации этой возможности воспользуемся отчетом о продажах, в котором будем использовать следующий запрос:

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

Результат отчета без дополнения будет выглядеть так:

Результат с дополнением по дням без указания интервала будет выглядеть так:

Т.е. дополнение произошло в интервале, дат, которые были получены из набора данных.

Если у поля группировки установить начальную и конечную дату периода следующим образом:


То дополнение по дням произойдет в указанном интервале и результат отчета будет выглядеть так:

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


Если в качестве начальной и/или конечной дат периода используется поле, то дополнение будет осуществляться до даты, полученной из этого поля. Заметим, что в качестве полей, значение которых будет использоваться для указания начальной или конечной даты периода, можно использовать только поля - параметры и поля отчета - владельца (в случае если дополнение происходит во вложенном отчете). Для примера, воспользуемся в качестве начальной даты полем - параметром - начало периода, а в качестве конечной даты - параметром - конец периода. При этом результат будет дополняться в том периоде, который указан в параметрах данных отчета.


Как видно в данном примере, дополнение произошло в интервале, указанном в параметрах данных.

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


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

Рассмотрим следующую настройку:


В отчет будут выдаваться периоды, сгруппированные по месяцам.

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

При дополнении в периоде 01.01.2002 - 31.03.2002 результат может выглядеть следующим образом:

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

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

Результат будет выглядеть так:

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

Читайте также: