Постановка задачи:
Есть таблица, в которой указаны дата возникновения долга и допустимое количество дней просрочки в рабочих днях. Для простоты добавим сам документ в таблицу.
Ссылка | Дата возникновения долга | Кол-во дней отсрочки |
---|---|---|
Док 1 | 04.03.2015 | 90 |
Док 2 | 04.03.2015 | 5 |
Док 3 | 04.03.2015 | 10 |
Док 4 | 05.03.2015 | 60 |
В результате должны получить таблицу вида
Ссылка | Дата возникновения долга | Кол-во дней отсрочки | Дата возникновения просроченного долга |
---|---|---|---|
Док 1 | 04.03.2015 | 90 | |
Док 2 | 04.03.2015 | 5 | |
Док 3 | 04.03.2015 | 10 | |
Док 4 | 05.03.2015 | 60 |
Первоначально был сделан отчет на СКД, куда помещался внешний набор данных. Но, посидев-покурив, решили сварганить запрос. И вот о нем и расскажу вам.
Реализация:
Первоначальные данные получаются следующим куском кода
ВЫБРАТЬ
РеализацияТоваровУслуг.Ссылка,
НАЧАЛОПЕРИОДА(РеализацияТоваровУслуг.Дата, ДЕНЬ) КАК Дата,
РеализацияТоваровУслуг.ДоговорКонтрагента.ДопустимоеЧислоДнейЗадолженности КАК ДнейОтсрочкиДолга
ПОМЕСТИТЬ ВТ
ИЗ
Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
Само собой получим Регламентированный производственный календарь.
ВЫБРАТЬ
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря
ПОМЕСТИТЬ ВТ_РеглКалендарь
ИЗ
РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
ГДЕ
РегламентированныйПроизводственныйКалендарь.ВидДня В(&ВидДня)
Здесь необходимо установить параметр "ВидДня" (значения перечисления Рабочий и Предпраздничный). Далее соединяем таблицу календаря саму с собой и получаем индекс даты (т.е. порядок следования записей) в нашей таблице
ВЫБРАТЬ
ВТ_РеглКалендарь.ДатаКалендаря,
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ_РеглКалендарь1.ДатаКалендаря) КАК ИндексРегламентированногоКалендаря
ПОМЕСТИТЬ ВТ_РеглКалендарьСИндексами
ИЗ
ВТ_РеглКалендарь КАК ВТ_РеглКалендарь
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_РеглКалендарь КАК ВТ_РеглКалендарь1
ПО ВТ_РеглКалендарь.ДатаКалендаря >= ВТ_РеглКалендарь1.ДатаКалендаря
СГРУППИРОВАТЬ ПО
ВТ_РеглКалендарь.ДатаКалендаря
ИНДЕКСИРОВАТЬ ПО
ИндексРегламентированногоКалендаря
Тут соединим таблицу ВТ и ВТ_РеглКалендарьСИндексами для того, что бы узнать какой индекс будет у нашей даты возникновения долга. Дополнительно добавим индексацию по расчетному полю для дальнейших соединений.
ВЫБРАТЬ
ВТ.Ссылка,
ВТ.Дата,
ВТ.ДнейОтсрочкиДолга,
ВТ_РеглКалендарьСИндексами.ИндексРегламентированногоКалендаря КАК ИндексДатыДолга
ПОМЕСТИТЬ ВТ_СИндексом
ИЗ
ВТ КАК ВТ
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_РеглКалендарьСИндексами КАК ВТ_РеглКалендарьСИндексами
ПО ВТ.Дата = ВТ_РеглКалендарьСИндексами.ДатаКалендаря
Здесь приведу результаты промежуточной таблицы для наглядности.
Ссылка | Дата возникновения долга | Кол-во дней отсрочки | Индекс даты долга |
---|---|---|---|
Док 1 | 04.03.2015 | 90 | 1 293 |
Док 2 | 04.03.2015 | 5 | 1 293 |
Док 3 | 04.03.2015 | 10 | 1 293 |
Док 4 | 05.03.2015 | 60 | 1 294 |
Здесь колонка "Индекс даты долга" показывает индекс поля "Дата возникновения долга" в таблице ВТ_РеглКалендарьСИндексами.
Далее мы можем получить результат "Дата возникновения просроченного долга" для каждой даты долга с учетом дней просрочки. Для этого соединим две таблицы.
ВЫБРАТЬ
ВТ_СИндексом.Ссылка,
ВТ_СИндексом.Дата КАК ДатаВозникновенияДолга,
ВТ_СИндексом.ДнейОтсрочкиДолга,
ВТ_РеглКалендарьСИндексами.ДатаКалендаря КАК ДатаВозникновенияПросроченногоДолга
ИЗ
ВТ_СИндексом КАК ВТ_СИндексом
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_РеглКалендарьСИндексами КАК ВТ_РеглКалендарьСИндексами
ПО (ВТ_РеглКалендарьСИндексами.ИндексРегламентированногоКалендаря - ВТ_СИндексом.ИндексДатыДолга = ВТ_СИндексом.ДнейОтсрочкиДолга)
Здесь условие соединения означает, что мы хотим получить только ту дату из таблицы ВТ_РеглКалендарьСИндексами, у которой разница Индекса регламентированного календаря и Индекса даты долга будет равно именно количеству дней отсрочки.
Результирующая таблица выглядит следующим образом:
Ссылка | Дата возникновения долга | Кол-во дней отсрочки | Дата возникновения просроченного долга |
---|---|---|---|
Док 1 | 04.03.2015 | 90 | 14.07.2015 |
Док 2 | 04.03.2015 | 5 | 12.03.2015 |
Док 3 | 04.03.2015 | 10 | 19.03.2015 |
Док 4 | 05.03.2015 | 60 |
02.06.2015 |
Результирующий запрос
ВЫБРАТЬ
РеализацияТоваровУслуг.Ссылка,
НАЧАЛОПЕРИОДА(РеализацияТоваровУслуг.Дата, ДЕНЬ) КАК Дата,
РеализацияТоваровУслуг.ДоговорКонтрагента.ДопустимоеЧислоДнейЗадолженности КАК ДнейОтсрочкиДолга
ПОМЕСТИТЬ ВТ
ИЗ
Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря
ПОМЕСТИТЬ ВТ_РеглКалендарь
ИЗ
РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
ГДЕ
РегламентированныйПроизводственныйКалендарь.ВидДня В(&ВидДня)
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_РеглКалендарь.ДатаКалендаря,
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ_РеглКалендарь1.ДатаКалендаря) КАК ИндексРегламентированногоКалендаря
ПОМЕСТИТЬ ВТ_РеглКалендарьСИндексами
ИЗ
ВТ_РеглКалендарь КАК ВТ_РеглКалендарь
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_РеглКалендарь КАК ВТ_РеглКалендарь1
ПО ВТ_РеглКалендарь.ДатаКалендаря >= ВТ_РеглКалендарь1.ДатаКалендаря
СГРУППИРОВАТЬ ПО
ВТ_РеглКалендарь.ДатаКалендаря
ИНДЕКСИРОВАТЬ ПО
ИндексРегламентированногоКалендаря
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ.Ссылка,
ВТ.Дата,
ВТ.ДнейОтсрочкиДолга,
ВТ_РеглКалендарьСИндексами.ИндексРегламентированногоКалендаря КАК ИндексДатыДолга
ПОМЕСТИТЬ ВТ_СИндексом
ИЗ
ВТ КАК ВТ
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_РеглКалендарьСИндексами КАК ВТ_РеглКалендарьСИндексами
ПО ВТ.Дата = ВТ_РеглКалендарьСИндексами.ДатаКалендаря
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_СИндексом.Ссылка,
ВТ_СИндексом.Дата КАК ДатаВозникновенияДолга,
ВТ_СИндексом.ДнейОтсрочкиДолга,
ВТ_РеглКалендарьСИндексами.ДатаКалендаря КАК ДатаВозникновенияПросроченногоДолга
ИЗ
ВТ_СИндексом КАК ВТ_СИндексом
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_РеглКалендарьСИндексами КАК ВТ_РеглКалендарьСИндексами
ПО (ВТ_РеглКалендарьСИндексами.ИндексРегламентированногоКалендаря - ВТ_СИндексом.ИндексДатыДолга = ВТ_СИндексом.ДнейОтсрочкиДолга)
Ссылки на другие публикации подобной темы:
//infostart.ru/public/99507/ Банковские дни запросом
//infostart.ru/public/166349/ Добавить к дате рабочие дни в запросе
//infostart.ru/public/320887/ Расчет рабочих дней в запросе
//infostart.ru/public/338386/ Расчет банковских (рабочих) дней (Оригинальный способ)
//infostart.ru/public/358354/ Прибавление банковских дней к дате в запросе