Поиск даты от текущей за вычетом выходных дней

29.11.18

Разработка - Универсальные функции

Простой способ поиска даты от текущей за вычетом выходных дней.

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

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

В данном примере приведен простой запрос который ищет день, который наступит через определенное количество дней за вычетом выходных дней. То есть допустим мне нужно добавить 5 дней, до текущей даты - 28.11.2018, данное число у меня приходится на среду, выходные дни - суббота и воскресенье. Фактически +5 дней это следующую рабочую неделю 5.12.2018.

  • Фактически мы передаем в запрос дату от которой будем считать дни
  • Ищем по номеру дня дату которая наступит через n - дней от даты среза, за вычетом выходных дней

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

ВЫБРАТЬ
	РегламентированныйПроизводственныйКалендарь.ДатаКалендаря КАК Дата,
	РегламентированныйПроизводственныйКалендарь.ВидДня
ПОМЕСТИТЬ ВТ1
ИЗ
	РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
ГДЕ
	РегламентированныйПроизводственныйКалендарь.ДатаКалендаря >= &ДатаСреза
	И РегламентированныйПроизводственныйКалендарь.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ11.Дата) КАК НомерДня,
	ВТ1.Дата,
	ВТ1.ВидДня
ИЗ
	ВТ1 КАК ВТ1
		ЛЕВОЕ СОЕДИНЕНИЕ ВТ1 КАК ВТ11
		ПО ВТ1.Дата > ВТ11.Дата

СГРУППИРОВАТЬ ПО
	ВТ1.Дата,
	ВТ1.ВидДня

ИМЕЮЩИЕ
	КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ11.Дата) = &НомерДня

УПОРЯДОЧИТЬ ПО
	НомерДня

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

ВЫБРАТЬ
	РегламентированныйПроизводственныйКалендарь.ДатаКалендаря КАК Дата,
	РегламентированныйПроизводственныйКалендарь.ВидДня
ПОМЕСТИТЬ ВТ1
ИЗ
	РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
ГДЕ
	ВЫБОР
			КОГДА &НомерДня > 0
				ТОГДА РегламентированныйПроизводственныйКалендарь.ДатаКалендаря >= &ДатаСреза
			ИНАЧЕ РегламентированныйПроизводственныйКалендарь.ДатаКалендаря <= &ДатаСреза
		КОНЕЦ
	И РегламентированныйПроизводственныйКалендарь.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ВЫБОР
		КОГДА &НомерДня > 0
			ТОГДА КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ11.Дата)
		ИНАЧЕ -КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ11.Дата)
	КОНЕЦ КАК НомерДня,
	ВТ1.Дата,
	ВТ1.ВидДня
ПОМЕСТИТЬ ВТ2
ИЗ
	ВТ1 КАК ВТ1
		ЛЕВОЕ СОЕДИНЕНИЕ ВТ1 КАК ВТ11
		ПО (ВЫБОР
				КОГДА &НомерДня > 0
					ТОГДА ВТ1.Дата > ВТ11.Дата
				ИНАЧЕ ВТ1.Дата < ВТ11.Дата
			КОНЕЦ)

СГРУППИРОВАТЬ ПО
	ВТ1.Дата,
	ВТ1.ВидДня
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ВТ2.НомерДня КАК НомерДня,
	ВТ2.Дата,
	ВТ2.ВидДня
ИЗ
	ВТ2 КАК ВТ2
ГДЕ
	ВТ2.НомерДня = &НомерДня

УПОРЯДОЧИТЬ ПО
	НомерДня

Что фактически изменил:

- в соответствии с переданым значением номера дня от даты среза  считаются дни вперед или назад от текущей даты

- если номер дня  со знаком минус считеам назад и наоборот

Также что хотелесь сказать знатокам мое решение не претендует на уникальность, если кому то поможет метод которым я решил свою проблему я буду очень рад

И в заверешение прикрепляю функцию для определения искоемого дня в стандартном модуле для УПП.  (спасибо AnSk) 

// Функция возвращает дату отстоящую на заданное количество рабочих дней от начальной в соответствии с
//регламентированным производственным календарем
//
//Параметры:
// ДатаНач      - начальная дата
// ЧислоДней    - количество рабочих дней, на которое искомая дата должна отстоять от начальной
//
Функция ОпределитьДату(ДатаНач, ЧислоДней) Экспорт
	
	Запрос = Новый  Запрос;
	Запрос.УстановитьПараметр("ДатаНач",             ДатаНач);
	Запрос.УстановитьПараметр("ЧислоДней",           ЧислоДней);
	Запрос.УстановитьПараметр("РабочийДень",         Перечисления.ВидыДнейПроизводственногоКалендаря.Рабочий);
	Запрос.УстановитьПараметр("ПредпраздничныйДень", Перечисления.ВидыДнейПроизводственногоКалендаря.Предпраздничный);
	
	Если ЧислоДней > 0 Тогда
		Запрос.Текст = "
		|ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ " + ЧислоДней + "
		|	РегламентированныйПроизводственныйКалендарь.ДатаКалендаря
		|ИЗ
		|	РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
		|ГДЕ РегламентированныйПроизводственныйКалендарь.ДатаКалендаря > &ДатаНач
		|	 И (РегламентированныйПроизводственныйКалендарь.ВидДня = &РабочийДень
		|      ИЛИ РегламентированныйПроизводственныйКалендарь.ВидДня = &ПредпраздничныйДень)
		|УПОРЯДОЧИТЬ ПО 
		|	ДатаКалендаря ВОЗР";
		
	Иначе
		ЧислоДней = -ЧислоДней;
		
		Запрос.Текст = "
		|ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ " + ЧислоДней + "
		|	РегламентированныйПроизводственныйКалендарь.ДатаКалендаря
		|ИЗ
		|	РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
		|ГДЕ РегламентированныйПроизводственныйКалендарь.ДатаКалендаря < &ДатаНач
		|	 И (РегламентированныйПроизводственныйКалендарь.ВидДня = &РабочийДень
		|      ИЛИ РегламентированныйПроизводственныйКалендарь.ВидДня = &ПредпраздничныйДень)
        |УПОРЯДОЧИТЬ ПО
		|	ДатаКалендаря УБЫВ
		|";
		
	КонецЕсли;
	
	Выборка = Запрос.Выполнить().Выбрать();
	
	Если Выборка.Количество() = ЧислоДней Тогда
		Пока Выборка.Следующий() Цикл
			ТекДата = Выборка.ДатаКалендаря;
		КонецЦикла;
		Возврат ТекДата;
	КонецЕсли;
	
	Возврат Неопределено;
	
КонецФункции

 

См. также

SALE! 15%

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

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

10000 руб.

02.09.2020    159657    875    399    

862

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

Столкнулся с интересной ситуацией, которую хотел бы разобрать, ввиду её неочевидности. Речь пойдёт про использование функции запроса АВТОНОМЕРЗАПИСИ() и проблемы, которые могут возникнуть.

11.10.2024    5198    XilDen    36    

80

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

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

21.05.2024    20238    dimanich70    81    

145

HighLoad оптимизация Запросы

Очень немногие из тех, кто занимается поддержкой MS SQL, работают с хранилищем запросов. А ведь хранилище запросов – это очень удобный, мощный и, главное, бесплатный инструмент, позволяющий быстро найти и локализовать проблему производительности и потребления ресурсов запросами. В статье расскажем о том, как использовать хранилище запросов в MS SQL и какие плюсы и минусы у него есть.

11.10.2023    19352    skovpin_sa    15    

105

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

28.08.2023    14774    YA_418728146    7    

166

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    3593    57    progmaster    8    

4

Запросы HighLoad оптимизация Программист Запросы Бесплатно (free)

Многие знают, что для ускорения работы запроса нужно «изучить план». При этом сам план обычно обескураживает: куча разноцветных иконок и стрелочек; ничего не понятно, но очень интересно! Аналитик производительности Александр Денисов на конференции Infostart Event 2021 Moscow Premiere рассказал, как выполняется план запроса и что нужно сделать, чтобы с его помощью находить проблемы производительности.

20.06.2023    28239    Филин    37    

118
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. dandykry 11 29.11.18 11:07 Сейчас в теме
КалендарныеГрафики.ДатыБлижайшихРабочихДней(ПроизводственныйКалендарь, МассивДат, Ложь, Ложь, Истина);
svilsa; JohnyDeath; triviumfan; SpartakM; rpgshnik; Mihaz1986; +6 Ответить
2. Mihaz1986 29.11.18 12:34 Сейчас в теме
(1)Всё уже написано за нас)
4. Mellow 59 29.11.18 13:23 Сейчас в теме
(2)на оригинальность не претендую возможно в других конфигурациях уже реализовано
3. Mellow 59 29.11.18 13:22 Сейчас в теме
(1)Ето для какой конфигурации, в упп нету такого
9. dandykry 11 29.11.18 14:22 Сейчас в теме
(3) А не вижу информации по поводу УПП. Написано для любой конфигурации (не правда)

http://prntscr.com/logwk3

мой код из БСП вроде бы
10. Mellow 59 29.11.18 15:01 Сейчас в теме
(9)Имеется ввиду что можна использовать для любой конфигурации в которой есть регламентировний производственний квлендарь, а тестировалось на упп и утп
11. dandykry 11 29.11.18 15:16 Сейчас в теме
(10) Ну в БСП производственных календарей может быть много) Не имеет значение. Хороший запрос
13. graf9190 30.11.18 15:54 Сейчас в теме
(9) В УПП нет, я делал так
Код
5. VmvLer 29.11.18 13:51 Сейчас в теме
то что автор дошел до решения сам - это да, почетно и похвально.

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

Правда некоторые "профи" тут на меня часто вопят, мол, читать общие модули
современных конфигураций - это чушь, велосипедить - сила.)
rpgshnik; +1 Ответить
7. Mellow 59 29.11.18 14:08 Сейчас в теме
(5) В конфигурациях УПП и УТП такого общего модуля как КалендарныеГрафики нет . Именно с ними работал
6. Serg O. 297 29.11.18 14:02 Сейчас в теме
только БЕЗ выходных - вообще можно БЕЗ всяких регистров найти,
просто в цикле, используя только 1 функцию ДеньНедели (Дата1)
Определяет номер дня недели для указанной даты и если она < 6 то добавляем в результат.
а праздников - не так много в году - можно как доп.условие добавить по функции День(Дата1) - в году
Vlad_2008; +1 1 Ответить
8. Mellow 59 29.11.18 14:09 Сейчас в теме
(6) Как по мене запрос более универсальней
18. Vlad_2008 16 05.12.18 15:32 Сейчас в теме
(8) Устойчивое заблуждение, которое тянется с эпохи 7.7 и толстых клиентов.
Каждому способу свое применение, где-то запрос, где-то код и универсальность тут не причем.
Думать надо об оптимальности и учитывать что теперь у нас клиент-серверное взаимодействие.
Запрос - это сервер, а вот кодом можно решить задачу с использованием только клиентского вызова, т.е. в каждом случае выбираем способ исходя из условий задачи, а не из универсальности ... БСП вспомнил ... универсально аж о...ть ... при печати, не помню какого документа, видел стек вызовов в 40 пунктов - идиотизм, там же ... в типовых бесит запрос вида "ВЫБРАТЬ Ссылка ИЗ Документ.БлаБла ГДЕ Ссылка = &ТекущийДрокумент" ... на хрена здесь "универсальный" запрос, ссылка уже у нас "в руках". Очень часто вижу, когда разработчики используют запросы там, где достаточной простой выборки по объектам. Печалька ...
svilsa; izidakg; +2 Ответить
12. AnSk 30.11.18 13:23 Сейчас в теме
УТП, модуль ЗаполнениеДокументов

// Функция возвращает дату отстоящую на заданное количество рабочих дней от начальной в соответствии с
//регламентированным производственным календарем
//
//Параметры:
// ДатаНач      - начальная дата
// ЧислоДней    - количество рабочих дней, на которое искомая дата должна отстоять от начальной
//
Функция ОпределитьДату(ДатаНач, ЧислоДней) Экспорт
Показать


// Функция возвращает число рабочих дней между заданными датами по регламентированному производственному календарю
//
//Параметры:
// ДатаНач      - начальная дата
// ДатаКон      - конечная дата
//
Функция ЧислоРабочихДней(ДатаНач, ДатаКон) Экспорт
Показать
akaNastenka; oliap; +2 Ответить
14. lunjio 67 03.12.18 14:52 Сейчас в теме
(12)
Надо ещё уточнить, что процедура прекрасно работает при поиске даты как в вперед, так и назад, при указании отрицательного числа, определяется соответствующая рабочая дата, а автора запрос работает только вперёд и никакого назад)
15. AnSk 03.12.18 18:54 Сейчас в теме
(14)
Главное задать направление поиска "несуществующих" процедур )
16. Mellow 59 03.12.18 19:11 Сейчас в теме
(12) В УТП даная функция считает количество рабочих дней между двумя датами, а не как в УПП возвращает дату отстоящую на заданное количество рабочих дней от начальной в соответствии с регламентированным производственным календарем
17. AnSk 04.12.18 09:51 Сейчас в теме
(16)
В сообщении описано две функции.
19. Cohap 6 14.04.23 11:35 Сейчас в теме
Максимально простой запрос для БСП.

ВЫБРАТЬ
	Сумма(1) КАК КоличествоДней
ИЗ
	РегистрСведений.КалендарныеГрафики КАК КалендарныеГрафики
ГДЕ
	КалендарныеГрафики.ДеньВключенВГрафик = ИСТИНА
	И КалендарныеГрафики.ДатаГрафика МЕЖДУ &Дата1 И &Дата2
20. dandykry 11 27.04.23 10:11 Сейчас в теме
21. Cohap 6 27.04.23 10:53 Сейчас в теме
(20) количество дней между двумя датами за вычетом тех дней, которые не включены в рабочий график.
22. dandykry 11 02.05.23 16:24 Сейчас в теме
(21) ааа... понял)) Туплю. В задаче дату ищут через n дней, а вы количество дней не включённых в график.
23. Cohap 6 03.05.23 09:55 Сейчас в теме
(22) ясно ) перечитаю я похоже бегло посмотрел.
Оставьте свое сообщение