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

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

Вопрос:
Необходимо посчитать количество дней между двумя датами ЗА ВЫЧЕТОМ ВЫХОДНЫХ ДНЕЙ (СУББОТ и ВОСКРЕСЕНИЙ).
Заранее благодарен!
...
Рейтинг: 0 / 0
12.01.2017, 15:10
    #39383239
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посчитать количество дней между двумя датами за вычетом выходных дней
Тебе без выходных или без суббот и воскресений? Суббота может быть рабочим днем, праздничные дни - выходные.
...
Рейтинг: 0 / 0
12.01.2017, 15:17
    #39383244
p672
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посчитать количество дней между двумя датами за вычетом выходных дней
устроит без суббот и воскресений
...
Рейтинг: 0 / 0
12.01.2017, 15:24
    #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
12.01.2017, 15:51
    #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
12.01.2017, 16:19
    #39383333
p672
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посчитать количество дней между двумя датами за вычетом выходных дней
Да дата1 всегда меньше даты2.
...
Рейтинг: 0 / 0
12.01.2017, 21:26
    #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
12.01.2017, 21:42
    #39383601
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посчитать количество дней между двумя датами за вычетом выходных дней
sg12,

на интервалах гораздо больших чем неделя, например год+, будет тормозить зазря.
...
Рейтинг: 0 / 0
12.01.2017, 22:40
    #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
13.01.2017, 08:20
    #39383731
p672
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посчитать количество дней между двумя датами за вычетом выходных дней
Алгоритм по вычету праздников тоже беру.
Спасибо большое ВСЕМ.
...
Рейтинг: 0 / 0
13.01.2017, 08:28
    #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
13.01.2017, 08:40
    #39383743
p672
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посчитать количество дней между двумя датами за вычетом выходных дней
Я попробовал эту функцию вставить в событие LOAD главной формы, FoxPro пишет что нельзя функцию туда добавлять.
А куда её добавить?
...
Рейтинг: 0 / 0
13.01.2017, 08:42
    #39383744
p672
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посчитать количество дней между двумя датами за вычетом выходных дней
А в массив или в курсор можно же календарь такой загрузить и пользоваться?!
...
Рейтинг: 0 / 0
13.01.2017, 08:48
    #39383747
p672
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посчитать количество дней между двумя датами за вычетом выходных дней
Есть производственный календарь на 2017 год с точными НЕрабочими датами.
Лучше всего создать массив описать туда все даты и пользоваться.
Последний вариант с запросом нравится.
...
Рейтинг: 0 / 0
13.01.2017, 08:53
    #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
13.01.2017, 09:00
    #39383754
p672
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посчитать количество дней между двумя датами за вычетом выходных дней
Пожалуйста сделайте запрос на количество часов под такие таблицы:
Этот вариант будет самый простой и лучший:

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

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

и запрос в одну строчку..
...
Рейтинг: 0 / 0
13.01.2017, 09:00
    #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
13.01.2017, 09:07
    #39383762
p672
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посчитать количество дней между двумя датами за вычетом выходных дней
Не рабочие дни в календарь совсем НЕ буду заносить.
В календаре будут только рабочие (8 часов) и сокращённые дни (7 часов).
...
Рейтинг: 0 / 0
13.01.2017, 09:09
    #39383764
p672
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посчитать количество дней между двумя датами за вычетом выходных дней
Календарь на весь 2017 год есть.
...
Рейтинг: 0 / 0
13.01.2017, 09:11
    #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
13.01.2017, 09:23
    #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
13.01.2017, 09:39
    #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
13.01.2017, 10:13
    #39383810
p672
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посчитать количество дней между двумя датами за вычетом выходных дней
Мне нужно добавить в выражение запроса условие:
Проставлять количество часов в RZ.H только в те записи у которых RZ.DK > RZ.DP
Как грамотно это сделать?
...
Рейтинг: 0 / 0
13.01.2017, 10:45
    #39383860
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посчитать количество дней между двумя датами за вычетом выходных дней
p672Мне нужно добавить в выражение запроса условие:
Проставлять количество часов в RZ.H только в те записи у которых RZ.DK > RZ.DP
Как грамотно это сделать?
Не надо ничего добавлять, такие записи вообще не попадут в результат запроса.
...
Рейтинг: 0 / 0
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Посчитать количество дней между двумя датами за вычетом выходных дней / 24 сообщений из 24, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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