Разбить период по месяцам в запросе 1с
Существует несколько способов получить нужные данные.
Непосредственно в запросе
Способ подходит практически для любой ситуации, и поэтому наиболее универсален. Единственный, пожалуй, минус этого способа - если в отчете пользователю не требуется курс, то запрос быдет выбирать избыточные данные.
Вызов СрезПоследних() можно использовать только с передачей в него заранее готового значения даты, на которую требуется получить значения. Поэтому сабж делается через стыковку нескольких запросов - основной, к нему стыкуется запрос по регистру сведений с условием по дате и поиском записи с маскимальной датой (периодом).
В 8.1. вместо обращения к курсам валют удобнее и надежнее использовать временную таблицу с нужными датами, потому что не во всех организациях ведут курсы валют ежедневно.
Для общего развития: Что есть срез последних в платформе?
В зависимости от периодичности регистра (по времени, по позизии регистратора) ВТ разворачивается в следующий запрос:
1. По времени (год, месяц, … секунда)
2. По позиции регистратора В данном случае нужно еще раз обернуть выборку
Все это можно увидеть посмотрев технологический журнал с включенным режимом протоколирования запросов.
Система компоновки данных
Данный способ подходит для отчетов. Из очевидных плюсов - если курс (или другие данные) не нужны для построения отчета, то СКД не будет их получать. Однако быстродействие такого отчета может оказаться и несколько ниже, чем в первом способе.
Для примера сделаем отчет - список заказов покупателей.
Для этого создадим набор данных «Документы» - запрос:
Для того, чтобы потом успешно свзать наборы данных, в запрос необходимо включить поля «Дата» и «ВалютаДокумента». Чтобы они не появлялись в списке доступных полей, если это необходимо, их можно убрать, установив флажки ограничений в таблице «Поля» схемы компоновки. В остальном запрос вряд ли требует комментариев.
Для того, чтобы получить информацию о курсах валют, добавим второй набор данных-запрос, «Курсы валют»:
В этом запросе имеются 2 параметра: «Дата» и «Валюта». Эти параметры будут установлены СКД при соединении наборов. Кроме того, параметр «Дата» указан в выбранных полях - это нужно для соединения таблиц. В этом запросе необходимо отключить галочку «Автозаполнение». Для ненужный полей «Дата» и «Валюта» также устанавливаем флажки ограничений, чтобы они не появлялись в доступных полях.
Перейдем к соединению наборов. На странице «Связи наборов данных» добавим 2 связи: 1. Источник связи - набор «Документы», приемник - набор «Курсы валют». Выражение источник - «Дата», выражение приемник - «Дата», Параметр - «Дата» 2. Источник связи - набор «Документы», приемник - набор «Курсы валют». Выражение источник - «ВалютаДокумента», выражение приемник - «Валюта», Параметр - «Валюта»
Главное здесь - параметры связи. При соединении наборов данных, если указан параметр, СКД передает в подчиненный набор (в нашем случае - запрос «Курсы валют») параметры, указанные в соединении. Значениями параметров будут значения соответствующих полей набора-источника.
Перейдем к вычисляемым полям. Добавим вычисляемое поле «СуммаВВалютеУпрУчета». Выражение поля - «СуммаДокумента * Курс / Кратность».
Также укажем поля «СуммаДокумента» и «СуммаВВалютеУпрУчета» как ресурсы
Настроим отчет. Добавим одну группировку «Детальные записи», в выбранных полях укажем «ЗаказПолкупателя», «Курс» и «Кратность». Добавим ресурсы «СуммаДокумента» и «СуммаВВалютеУпрУчета»
Можно формировать отчет
- Последние изменения: 03.04.2022 22:07
- — Asmody
За исключением случаев, когда указано иное, содержимое этой вики предоставляется на условиях следующей лицензии: CC Attribution-Share Alike 3.0 Unported
1С 8.3 Разбить период по подпериодам (месяц, неделя, день, квартал)
Аналоги типовой функции РазложитьНаПериоды (запросом или через цикл). Методы использовались для разбиения периода в нетиповых решениях. Делят любой период (между начальной и конечной датой) по нужным отрезкам: месяц, неделя, день, квартал.
&НаСервере
Функция ЗапросомРазбитьПериодНаПодпериоды ( Знач НачДата , Знач КонДата )
// например НачДата 05.05.2021, КонДата 27.09.2021
Запрос . УстановитьПараметр ( "НачДата" , НачДата );
Запрос . УстановитьПараметр ( "КонДата" , КонДата );
РезультатЗапроса = Запрос . Выполнить ();
Если Не РезультатЗапроса . Пустой () Тогда // Такая проверка рекомендуется фирмой 1С
Записи = РезультатЗапроса . Выбрать ( ОбходРезультатаЗапроса . ПоГруппировкам , "Период" , "ВСЕ" );
// Обход результата запроса по каждой записи в полученной выборке
Пока Записи . Следующий () Цикл
Сообщить ( Записи . Период );
// 01.05.2021 0:00:00
// 01.06.2021 0:00:00
// 01.07.2021 0:00:00
// 01.08.2021 0:00:00
// 01.09.2021 0:00:00
//Год_Даты = СокрЛП(Год(Записи.Период)); // 2 021
//Месяц_Даты = СокрЛП(Месяц(Записи.Период)); // 9
//Сообщить(Год_Даты+" "+Месяц_Даты);
КонецЦикла;
Иначе // Например: Сообщить("Данные отсутствуют!");
КонецЕсли;
&НаСервере
Функция РазбитьПериодНаПодпериоды ( Знач НачДата , Знач КонДата , УровеньДетализации )
ТаблицаДат = Новый ТаблицаЗначений ;
ТаблицаДат . Колонки . Добавить ( "НачДата" );
ТаблицаДат . Колонки . Добавить ( "КонДата" );
ПервыйОбходЦикла = Истина;
Если УровеньДетализации = "День" Тогда
Пока НачДата Если ПервыйОбходЦикла Тогда
Если КонецДня ( НачДата ) >= КонДата Тогда
НоваяСтрока = ТаблицаДат . Добавить ();
НоваяСтрока . НачДата = НачДата ;
НоваяСтрока . КонДата = КонДата ;
Прервать;
Иначе
НоваяСтрока = ТаблицаДат . Добавить ();
НоваяСтрока . НачДата = НачДата ;
НоваяСтрока . КонДата = КонецДня ( НачДата );
КонецЕсли;
Иначе
Если КонецДня ( НачДата ) >= КонДата Тогда
НоваяСтрока = ТаблицаДат . Добавить ();
НоваяСтрока . НачДата = НачалоДня ( НачДата );
НоваяСтрока . КонДата = КонДата ;
Прервать;
Иначе
НоваяСтрока = ТаблицаДат . Добавить ();
НоваяСтрока . НачДата = НачалоДня ( НачДата );
НоваяСтрока . КонДата = КонецДня ( НачДата );
КонецЕсли;
КонецЕсли;
НачДата = КонецДня ( НачДата )+ 1 ;
ПервыйОбходЦикла = Ложь;
КонецЦикла;
Пока НачДата Если ПервыйОбходЦикла Тогда
Если КонецНедели ( НачДата ) >= КонДата Тогда
НоваяСтрока = ТаблицаДат . Добавить ();
НоваяСтрока . НачДата = НачДата ;
НоваяСтрока . КонДата = КонДата ;
Прервать;
Иначе
НоваяСтрока = ТаблицаДат . Добавить ();
НоваяСтрока . НачДата = НачДата ;
НоваяСтрока . КонДата = КонецНедели ( НачДата );
КонецЕсли;
Иначе
Если КонецНедели ( НачДата ) >= КонДата Тогда
НоваяСтрока = ТаблицаДат . Добавить ();
НоваяСтрока . НачДата = НачалоНедели ( НачДата );
НоваяСтрока . КонДата = КонДата ;
Прервать;
Иначе
НоваяСтрока = ТаблицаДат . Добавить ();
НоваяСтрока . НачДата = НачалоНедели ( НачДата );
НоваяСтрока . КонДата = КонецНедели ( НачДата );
КонецЕсли;
КонецЕсли;
НачДата = КонецНедели ( НачДата )+ 1 ;
ПервыйОбходЦикла = Ложь;
КонецЦикла;
Пока НачДата Если ПервыйОбходЦикла Тогда
Если КонецМесяца ( НачДата ) >= КонДата Тогда
НоваяСтрока = ТаблицаДат . Добавить ();
НоваяСтрока . НачДата = НачДата ;
НоваяСтрока . КонДата = КонДата ;
Прервать;
Иначе
НоваяСтрока = ТаблицаДат . Добавить ();
НоваяСтрока . НачДата = НачДата ;
НоваяСтрока . КонДата = КонецМесяца ( НачДата );
КонецЕсли;
Иначе
Если КонецМесяца ( НачДата ) >= КонДата Тогда
НоваяСтрока = ТаблицаДат . Добавить ();
НоваяСтрока . НачДата = НачалоМесяца ( НачДата );
НоваяСтрока . КонДата = КонДата ;
Прервать;
Иначе
НоваяСтрока = ТаблицаДат . Добавить ();
НоваяСтрока . НачДата = НачалоМесяца ( НачДата );
НоваяСтрока . КонДата = КонецМесяца ( НачДата );
КонецЕсли;
КонецЕсли;
НачДата = КонецМесяца ( НачДата )+ 1 ;
ПервыйОбходЦикла = Ложь;
КонецЦикла;
Пока НачДата Если ПервыйОбходЦикла Тогда
Если КонецКвартала ( НачДата ) >= КонДата Тогда
НоваяСтрока = ТаблицаДат . Добавить ();
НоваяСтрока . НачДата = НачДата ;
НоваяСтрока . КонДата = КонДата ;
Прервать;
Иначе
НоваяСтрока = ТаблицаДат . Добавить ();
НоваяСтрока . НачДата = НачДата ;
НоваяСтрока . КонДата = КонецКвартала ( НачДата );
КонецЕсли;
Иначе
Если КонецКвартала ( НачДата ) >= КонДата Тогда
НоваяСтрока = ТаблицаДат . Добавить ();
НоваяСтрока . НачДата = НачалоКвартала ( НачДата );
НоваяСтрока . КонДата = КонДата ;
Прервать;
Иначе
НоваяСтрока = ТаблицаДат . Добавить ();
НоваяСтрока . НачДата = НачалоКвартала ( НачДата );
НоваяСтрока . КонДата = КонецКвартала ( НачДата );
КонецЕсли;
КонецЕсли;
НачДата = КонецКвартала ( НачДата )+ 1 ;
ПервыйОбходЦикла = Ложь;
КонецЦикла;
Аналог типовой функции РазложитьНаПериоды(ДатаНачала = '00010101', ДатаОкончания = '00010101') , только релизовано на языке запросов. Не удалось найти готового решения, поэтому выкладываю запрос по разбиению периода на помесячные интервалы тут.
Специальные предложения
(16) давайте я поясню свою мысль.
Предложенное вами решение без должного основания использует зависимости:
1) от наличия в составе конфигурации такого объекта как регистр сведений "РегламентированныйПроизводственныйКалендарь";
2) от его правильной заполненности на нужный период.
Если первая зависимость легко проверяется (при попытке использовать этот метод в конфигурации без календаря, вы просто получите ошибку), то вторая зависимость неприятнее. При частичной заполненности календаря вы получите ошибку в отчете, которую еще потребуется поискать.
Кроме того, используемый принцип совершенно зря перебирает все даты периода, когда из месяца требуется только одна запись. То есть работает в 30 раз медленнее возможного.
Вопрос, наверное не такой уж важный, но тут много начинающих, которые используют готовый код, никак его не осмысливая. В результате чего недостаточно проработанные, сделанные на скорую руку решения множатся. Авторы публикаций могли бы этому препятствовать, а вы, кажется, способствуете.
Кстати, если уж настаиваете на использовании календаря, могу предложить вот такой вариант из одного запроса:
Он короче и более универсальный - легко вид периода (день, месяц, год, квартал) поменять.
А вообще в свете вопроса (15) можно было бы и конкурс объявить на решение этой задачи без календаря.
Существует несколько способов получить нужные данные.
Непосредственно в запросе
Способ подходит практически для любой ситуации и поэтому наиболее универсален. Единственный,
пожалуй, минус этого способа - если в отчете пользователю не требуется курс, то запрос будет
выбирать избыточные данные.
Вызов СрезПоследних() можно использовать только с передачей в него заранее готового значения даты,
на которую требуется получить значения. Поэтому сабж делается через стыковку нескольких запросов -
основной, к нему стыкуется запрос по регистру сведений с условием по дате и поиском записи с
маскимальной датой (периодом).
В 8.1. вместо обращения к курсам валют удобнее и надежнее использовать временную таблицу с нужными
датами, потому что не во всех организациях ведут курсы валют ежедневно. ;-)
Для общего развития:
Что есть срез последних в платформе?
В зависимости от периодичности регистра (по времени, по позиции регистратора) ВТ разворачивается в
следующий запрос:
1. По времени (год, месяц, . секунда)
2. По позиции регистратора
В данном случае нужно еще раз обернуть выборку
Все это можно увидеть посмотрев технологический журнал с включенным режимом протоколирования
запросов
Система компоновки данных
Данный способ подходит для отчетов. Из очевидных плюсов - если курс (или другие данные) не нужны для
построения отчета, то СКД не будет их получать. Однако быстродействие такого отчета может оказаться
и несколько ниже, чем в первом способе.
Для примера сделаем отчет - список заказов покупателей.
Для этого создадим набор данных "Документы" - запрос:
Для того, чтобы получить информацию о курсах валют, добавим второй набор данных - запрос "Курсы
валют":
Главное здесь - параметры связи. При соединении наборов данных, если указан параметр, СКД передает в подчиненный набор (в нашем случае - запрос "Курсы валют") параметры, указанные в соединении.
Значениями параметров будут значения соответствующих полей набора-источника.
В запросе задаем период отборки. Отчет на основании запроса. Как выводить в отчете период отборки?
В запросе задаем период отборки. Отчет на основании запроса. Как выводить в отчете период отборки.
Дата по рабочим дням в запросе
Добрый день. УТ 10 В документе Реализация добавлен реквизит.
Сортировка по дням рождения в запросе
Добрый день. SELECT DateSerial(Year(Date()), Month(), Day()) AS Дни, Сотрудники.ДеньРождения.
есть период с 01.01.2013 по 04.04.2013, нужно чтобы в запросе вывелось 01.01.2013, 02.01.2013, 03.01.2013, 04.01.2013.
к сожалению тоже не мой. А так задача состоит в том что строится отчет за период где по дням можно посмотреть занят номер или нет
1. Для конструкции ИТОГИ есть возможность указания доп. параметра ПЕРИОДАМИ.
2. В типовых конфигурациях есть регистр сведений РегламентированныйПроизводственныйКалендарь, можно выбирать дни из него.
вар 1 (топор): в цикле загони в таблицу дни между границами, таблицу сунь в запрос;
вар 2 (по конкретным обстоятельствам): если по этим периодам будешь выбирать с оборотного регистра - можно указать переодичность в запросе у самого регистра (см.скрин);
вар 3.
" по дням можно посмотреть занят номер или нет" - уточни более детально, что делаешь запросом
Перекрестная таблица в СКД тут вот должно получиться то что в итоге. Вторая картинка
Добавлено через 11 часов 21 минуту
1. Для конструкции ИТОГИ есть возможность указания доп. параметра ПЕРИОДАМИ.
2. В типовых конфигурациях есть регистр сведений РегламентированныйПроизводственныйКалендарь, можно выбирать дни из него.
Joker_vad, Странно, что Вы не прислушались к верному совету. Если нужны дни, а РС.РегламентированныйПроизводственныйКалендарь отсутствует, создайте ТЗ с датами и включите в источники СКД
Странно, что Вы не прислушались к верному совету. Если нужны дни, а РС.РегламентированныйПроизводственныйКалендарь отсутствует, создайте ТЗ с датами и включите в источники СКД
честно не знаю как это сделать. В виртуальной таблице использовать итоги нельзя. А как еще это прикрутить понять не могу
ЛЕВОЕ СОЕДИНЕНИЕ с датами по периоду День или ещё по какой - это по структуре данных уж соображать. ЕстьНАЛЛ и ВЫБОР КОГДА довершат дело.
Разбить период на подпериоды
Здравствуйте, столкнулся с такой проблемой, есть период с 1.10.16 по 31.10.16, он разбит в таблице.
Разбить некий временной период
Задача, подскажите в каком двигаться на майскле: Есть некий временной интервал t0, t1 : TIME.
Разбить период дат на заданные периоды
Добрый день всем! Задан период дат типа 01.01.2020 - 31.05.2020 Необходимо разбить его на.
Читайте также: