Введение:
Некоторые говорят о том чего не знают, другие знают, но не могут об этом сказать.
Итак, имеется на моем балансе самопальная конфигурация со всякими отчетами и обработками, в которых, в зависимости от области ее действия необходимо рассчитать срок наступления определенного события в рабочих днях, такого как:
- Ожидаемый срок поставки товара по заказу, в зависимости от количества дней поставки
- Срок оплаты покупателем, в зависимости от отсрочки платежа
- Срок оплаты поставщику за товары, в зависимости от его отсрочки нам
Сделано там "красиво", после выполнения запроса идет перебор результата в цикле и там ижи с ними расчет от производственного календаря.
Решил сделать все в запросе в целях оптимизации.
Выкладываю для варианта Оплата поступления по отсрочке в рабочих днях.
Параметр Организация думаю понятен
На выходе таблица с поступлениями и датами их оплаты
Работает хорошо, быстро.
ВЫБРАТЬ
ДоговорыКонтрагентов.Ссылка КАК Договор,
Контрагенты.Ссылка КАК Контрагент,
ДоговорыКонтрагентов.ДопустимоеЧислоДнейЗадолженности
ПОМЕСТИТЬ ВТ_Договора
ИЗ
Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты
ПО ДоговорыКонтрагентов.Владелец = Контрагенты.Ссылка
ГДЕ
ДоговорыКонтрагентов.ВидДоговора = ЗНАЧЕНИЕ(Перечисление.ВидыДоговоровКонтрагентов.СПоставщиком)
И ДоговорыКонтрагентов.КонтролироватьЧислоДнейЗадолженности
ИНДЕКСИРОВАТЬ ПО
Договор
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ПоступлениеТоваровУслуг.Контрагент.ГоловнойКонтрагент КАК ЮрЛицо,
ПоступлениеТоваровУслуг.Контрагент КАК Контрагент,
ПоступлениеТоваровУслуг.Ссылка КАК Поступление,
ПоступлениеТоваровУслуг.СуммаДокумента КАК Сумма,
НАЧАЛОПЕРИОДА(ПоступлениеТоваровУслуг.Дата, ДЕНЬ) КАК ДатаПоступления,
ВТ_Договора.ДопустимоеЧислоДнейЗадолженности
ПОМЕСТИТЬ ВТ_Поступления
ИЗ
Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Договора КАК ВТ_Договора
ПО ПоступлениеТоваровУслуг.ДоговорКонтрагента = ВТ_Договора.Договор
ГДЕ
ПоступлениеТоваровУслуг.Проведен
И ПоступлениеТоваровУслуг.Организация = &Организация
И ПоступлениеТоваровУслуг.СчетУчетаРасчетовСКонтрагентом В (ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.РасчетыСПоставщиками), ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.РасчетыПоАвансамВыданным))
ИНДЕКСИРОВАТЬ ПО
ДатаПоступления
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря КАК ДатаКалендаря
ПОМЕСТИТЬ ВТ_Календарь
ИЗ
РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Поступления КАК ВТ_Поступления
ПО РегламентированныйПроизводственныйКалендарь.ДатаКалендаря >= ВТ_Поступления.ДатаПоступления
ГДЕ
РегламентированныйПроизводственныйКалендарь.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
ИНДЕКСИРОВАТЬ ПО
ДатаКалендаря
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ_КалендарьПредыдущий.ДатаКалендаря) КАК ЧислоДаты,
ВТ_Календарь.ДатаКалендаря КАК ДатаКалендаря
ПОМЕСТИТЬ ВТ_КалендарьПоПорядку
ИЗ
ВТ_Календарь КАК ВТ_Календарь
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Календарь КАК ВТ_КалендарьПредыдущий
ПО ВТ_Календарь.ДатаКалендаря > ВТ_КалендарьПредыдущий.ДатаКалендаря
СГРУППИРОВАТЬ ПО
ВТ_Календарь.ДатаКалендаря
ИНДЕКСИРОВАТЬ ПО
ДатаКалендаря
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_Поступления.Контрагент,
ВТ_Поступления.Поступление,
ВТ_Поступления.Сумма,
ВТ_Поступления.ДатаПоступления,
ВТ_Поступления.ДопустимоеЧислоДнейЗадолженности,
ВТ_КалендарьПоПорядку.ЧислоДаты КАК ЧислоДаты,
ВТ_КалендарьПоПорядку.ДатаКалендаря,
ВТ_КалендарьПоПорядку.ЧислоДаты + ЕСТЬNULL(ВТ_Поступления.ДопустимоеЧислоДнейЗадолженности, 0) КАК ЧислоДатыПлюс
ПОМЕСТИТЬ Вт_ПромИтог
ИЗ
ВТ_Поступления КАК ВТ_Поступления
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_КалендарьПоПорядку КАК ВТ_КалендарьПоПорядку
ПО ВТ_Поступления.ДатаПоступления = ВТ_КалендарьПоПорядку.ДатаКалендаря
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Вт_ПромИтог.Контрагент,
Вт_ПромИтог.Поступление,
Вт_ПромИтог.Сумма,
Вт_ПромИтог.ДатаПоступления КАК ДатаПоступления,
Вт_ПромИтог.ДопустимоеЧислоДнейЗадолженности,
ВТ_КалендарьПоПорядку.ДатаКалендаря КАК ДатаОплаты
ИЗ
Вт_ПромИтог КАК Вт_ПромИтог
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_КалендарьПоПорядку КАК ВТ_КалендарьПоПорядку
ПО Вт_ПромИтог.ЧислоДатыПлюс = ВТ_КалендарьПоПорядку.ЧислоДаты
УПОРЯДОЧИТЬ ПО
ДатаПоступления
UPD
Столкнулся с моментом когда Поступление выпадает на выходной день оно не попадает в оплату. Для решения этой ситуации нужно перед таблицей т_Поступления разместить такую конструкцию:
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря КАК ДатаКалендаря
ПОМЕСТИТЬ ВТ_Календарь
ИЗ
РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
ГДЕ
РегламентированныйПроизводственныйКалендарь.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря КАК ДатаКалендаря
ПОМЕСТИТЬ ВТ_КалендарьВесь
ИЗ
РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_Календарь.ДатаКалендаря,
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ_КалендарьВесь.ДатаКалендаря) КАК ДатаКалендаря1
ПОМЕСТИТЬ КалендарьСЧисломВыходногоДня
ИЗ
ВТ_КалендарьВесь КАК ВТ_Календарь
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Календарь КАК ВТ_КалендарьВесь
ПО ВТ_Календарь.ДатаКалендаря >= ВТ_КалендарьВесь.ДатаКалендаря
СГРУППИРОВАТЬ ПО
ВТ_Календарь.ДатаКалендаря
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_Календарь.ДатаКалендаря,
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ_Календарь1.ДатаКалендаря) КАК ДатаКалендаря1
ПОМЕСТИТЬ ДатыПономеруДняКалендаря
ИЗ
ВТ_Календарь КАК ВТ_Календарь
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Календарь КАК ВТ_Календарь1
ПО ВТ_Календарь.ДатаКалендаря >= ВТ_Календарь1.ДатаКалендаря
СГРУППИРОВАТЬ ПО
ВТ_Календарь.ДатаКалендаря
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ДатыПономеруДняКалендаря.ДатаКалендаря ДатаприходаРабочая,
КалендарьСЧисломВыходногоДня.ДатаКалендаря КАК датаПриходаПолная
ИЗ
КалендарьСЧисломВыходногоДня КАК КалендарьСЧисломВыходногоДня
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ДатыПономеруДняКалендаря КАК ДатыПономеруДняКалендаря
ПО КалендарьСЧисломВыходногоДня.ДатаКалендаря1 = ДатыПономеруДняКалендаря.ДатаКалендаря1
данная конструкция определяет какая дата для выходного дня является рабочей, в данном случае это предыдущий рабочий день.
Далее с помощью соединения с таблицей ВТ_Поступления заменяем дату поступления на рабочую дату.