powered by simpleCommunicator - 2.0.40     © 2025 Programmizd 02
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Посчитать количество дней между двумя датами за вычетом выходных дней
24 сообщений из 24, страница 1 из 1
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383215
p672
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имеется в наличии Visual FoxPro 9 SP2
Имеется в наличии таблица RZ.DBF , в ней 3 поля :

D1 тип DATE (дата)
D2 тип DATE (дата)
R тип INTEGER (целое число) - разница (количество дней между датами D1 и D2)

Вопрос:
Необходимо посчитать количество дней между двумя датами ЗА ВЫЧЕТОМ ВЫХОДНЫХ ДНЕЙ (СУББОТ и ВОСКРЕСЕНИЙ).
Заранее благодарен!
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383239
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тебе без выходных или без суббот и воскресений? Суббота может быть рабочим днем, праздничные дни - выходные.
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383244
p672
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
устроит без суббот и воскресений
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383252
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Особо не тестил, но вроде правильно работает
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
? CalcDays(date() - 10, date())

func CalcDays
lpara tdStart, tdEnd
* Выравниваем до рабочих дней
do while IsSkipDay(tdStart)
	tdStart = tdStart + 1
enddo

* Расчет дней в полных неделях
lnRes = tdEnd - tdStart
lnRes = lnRes - lnRes % 7
tdStart = tdStart + lnRes
lnRes = lnRes - int(lnRes / 7)

* Дорасчет остатка
do while tdStart < tdEnd
	if !IsSkipDay(tdStart)
		lnRes = lnRes + 1
	endif
	tdStart = tdStart + 1
enddo
return lnRes

* Возвращает .T. если день надо пропустить
func IsSkipDay
lpara tdDay
return inlist(dow(tdDay), 1, 7)
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383291
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Написал тест для проверки
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
for i = 0 to 100
	ldEnd = date() - i
	for j = 0 to 100
		ldStart = ldEnd - j
		if CalcDays(ldStart, ldEnd) != Check(ldStart, ldEnd)
			? ldStart, ldEnd
			cancel
		endif
	endfor
endfor
return

func Check
lpara tdStart, tdEnd
lnRes = 0
do while tdStart <= tdEnd
	if !IsSkipDay(tdStart)
		lnRes = lnRes + 1
	endif
	tdStart = tdStart + 1
enddo
return lnRes


Напутал немного, так точно считает.
Начальный и конечный день входят в считаемый интервал.
Считает исходя из того что всегда tdStart <= tdEnd
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
func CalcDays
lpara tdStart, tdEnd
local lnRes
* Выравниваем до рабочих дней
do while IsSkipDay(tdStart)
	tdStart = tdStart + 1
enddo

* Расчет дней в полных неделях
lnRes = tdEnd - tdStart
lnRes = lnRes - lnRes % 7
tdStart = tdStart + lnRes
lnRes = lnRes - int(lnRes / 7) * 2
* Дорасчет остатка
do while tdStart <= tdEnd
	if !IsSkipDay(tdStart)
		lnRes = lnRes + 1
	endif
	tdStart = tdStart + 1
enddo
return lnRes

* Возвращает .T. если день надо пропустить
func IsSkipDay
lpara tdDay
return inlist(dow(tdDay), 1, 7)
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383333
p672
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да дата1 всегда меньше даты2.
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383593
sg12
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ld1 = DATE(2017,1,1)
ld2 = DATE(2017,1,8) && до
lcPr = "20170101,20170102,20170103,20170104" && Праздники
i = 0
DO WHILE ld1 < ld2
i = IIF(INLIST(DOW(ld1,2),6,7) OR DTOS(ld1)$lcPr,i,i+1)
ld1 = ld1 + 1
ENDDO
RETURN i
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383601
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sg12,

на интервалах гораздо больших чем неделя, например год+, будет тормозить зазря.
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383628
sg12
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tsg12,

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

Будет или тормозит - сколько и насколько?

Еще один цикл, для тормозов:
ld1 = DATE(2017,1,1)
ld2 = DATE(2022,1,8) && до
lcPr = '20170101,20170102,20170103,20170104' && Праздники
lnLen = ld2 - ld1
j = 0
FOR i = 1 TO lnLen
j = IIF(INLIST(DOW(ld1,2),6,7) OR DTOS(ld1)$lcPr,j,j+1)
ld1 = ld1 + 1
ENDFOR
RETURN j
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383731
p672
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алгоритм по вычету праздников тоже беру.
Спасибо большое ВСЕМ.
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383736
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По хорошему эта задача решается построением таблицы-календаря
DATEIS_WORK13.01.17.T.14.01.17.F.......
Код: sql
1.
select count(*) from Calendar where IS_WORK and DATE between ldStart and ldEnd
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383743
p672
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я попробовал эту функцию вставить в событие LOAD главной формы, FoxPro пишет что нельзя функцию туда добавлять.
А куда её добавить?
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383744
p672
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А в массив или в курсор можно же календарь такой загрузить и пользоваться?!
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383747
p672
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть производственный календарь на 2017 год с точными НЕрабочими датами.
Лучше всего создать массив описать туда все даты и пользоваться.
Последний вариант с запросом нравится.
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383751
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
p672Я попробовал эту функцию вставить в событие LOAD главной формы, FoxPro пишет что нельзя функцию туда добавлять.
А куда её добавить?
делаешь MY_PROC.PRG, туда все свои функции и при старте проги
Код: sql
1.
set proc to MY_PROC


или просто CalcDays.prg а в нем
Код: sql
1.
2.
lpara tdStart, tdEnd
...
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383754
p672
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пожалуйста сделайте запрос на количество часов под такие таблицы:
Этот вариант будет самый простой и лучший:

Таблица рабочая RZ.DBF :
DP тип DATE (дата начала)
DK тип DATE (дата конца)
R тип INTEGER (количество часов рабочих) (нужно посчитать и заполнить)

Таблица календарь KA.DBF :
D тип DATE (дата)
H тип INTEGER (количество часов) ( обычный день 8 часов, сокращённый день 7 часов, НЕ рабочий день 0 часов или лучше вообще нет в таблице)

и запрос в одну строчку..
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383755
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
p672Есть производственный календарь на 2017 год с точными НЕрабочими датами.
Если есть с нерабочими, то сначала считаешь сколько всего дней
Код: sql
1.
tdEnd - tdStart + 1


затем считаешь и вычитаешь нерабочие
Код: sql
1.
select count(*) from Calendar where DATE between ldStart and ldEnd


только следи чтобы календарь полностью перекрывал период.
p672Лучше всего создать массив описать туда все даты и пользоваться.
Последний вариант с запросом нравится.
Лучше курсор и индекс по DATE
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383762
p672
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не рабочие дни в календарь совсем НЕ буду заносить.
В календаре будут только рабочие (8 часов) и сокращённые дни (7 часов).
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383764
p672
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Календарь на весь 2017 год есть.
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383765
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
p672Пожалуйста сделайте запрос на количество часов под такие таблицы:...
В RZ наверно какой-то RZ_ID уникальный есть, без него не получится запрос, с ним так
Код: sql
1.
select RZ_ID, sum(H) from RZ join KA on КА.В between RZ.DP and RZ.DK group by RZ_ID
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383771
p672
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот так я собираюсь делать:

SELECT * FROM KA INTO CURSOR KA1
SELECT RZ IN 0
select NOMDOK, sum(H) from RZ join KA1 on КА1.В between RZ.DP and RZ.DK group by NOMDOK

NOMDOK - в RZ уникальное поле типа INTEGER - не повторяется.

А что такое КА.В в запросе?! (это наверное имелось в виду КА.D)
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383786
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
p672Вот так я собираюсь делать:

SELECT * FROM KA INTO CURSOR KA1
SELECT RZ IN 0
select NOMDOK, sum(H) from RZ join KA1 on КА1.В between RZ.DP and RZ.DK group by NOMDOK

NOMDOK - в RZ уникальное поле типа INTEGER - не повторяется.
Если KA1 используется один раз, то он тут лишний, используй KA в запросе. В курсор копировать имеет смысл если тебе надо многократно его использовать. Чтение из курсора быстрее чем из расшаренной таблицы, особенно если она где-то в сети.

И индекс не забывай
Код: sql
1.
2.
SELECT * FROM KA INTO CURSOR KA1
index on D tag D


p672А что такое КА.В в запросе?! (это наверное имелось в виду КА.D)
Опечатка, на английский не переключился, КА.D
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383810
p672
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мне нужно добавить в выражение запроса условие:
Проставлять количество часов в RZ.H только в те записи у которых RZ.DK > RZ.DP
Как грамотно это сделать?
...
Рейтинг: 0 / 0
Посчитать количество дней между двумя датами за вычетом выходных дней
    #39383860
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
p672Мне нужно добавить в выражение запроса условие:
Проставлять количество часов в RZ.H только в те записи у которых RZ.DK > RZ.DP
Как грамотно это сделать?
Не надо ничего добавлять, такие записи вообще не попадут в результат запроса.
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Посчитать количество дней между двумя датами за вычетом выходных дней
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]