|
Вопрос # 6 041/ вопрос решён / |
|
Здравствуйте уважаемые эксперты! Как в Delphi вычислить количество рабочих часов в текущем месяце и занести результат, например, в компонет TextEdit, при условии, что: 5-ти дневная, 8-ми часовая рабочая неделя, два выходных: суббота, воскресенье. Если есть праздничные дни их тоже исключить из расчета рабочего времени. Если можно, приведите подробный пример. Заранее Спасибо!
 |
Вопрос задал: stales (статус: 1-ый класс)
Вопрос отправлен: 2 апреля 2012, 11:01
Состояние вопроса: решён, ответов: 1.
|
Ответ #1. Отвечает эксперт: Мережников Андрей
Здравствуйте, stales!
Неправильно работает потому, что неправильно используется функция DayOfWeek - значение 1 - воскресенье, 7 - суббота (достаточно посмотреть хелп). Вот пример функции - на работоспособность не проверял. Данная функция не в состоянии определить праздничный нерабочий день, так же, как и не может знать о переносах выходных.
function WorkDay(d:TDate;c: byte = 5):Integer;
var vd,endD:TDate;
Yr,Mn,Dy:integer;
begin
Result:=0;
DecodeDate(d,Yr,Mn,Dy);
vd:=EncodeDate(Yr,Mn,1);
endD:=EndOfAMonth(Yr,Mn);
while vd<=endD
do begin
if DayOfTheWeek(vd)<6
then inc(Result)
else if (c>5)and(DayOfTheWeek(vd)=6)
then inc(Result);
vd:=IncDay(vd);
end;
end;
 |
Ответ отправил: Мережников Андрей (статус: Абитуриент)
Время отправки: 2 апреля 2012, 18:18
Оценка за ответ: 5
Комментарий к оценке: Андрей Спасибо! Получилось! Только не много пришлось подправить код. Там где у Вас идет объявление переменных
var vd, endD: Tdate;
Yr, Mn, Dy: Word - вот нужно было какой параметр поставить и все, код заработал! Огромное спасибо!!!
|
Мини-форум вопроса
Всего сообщений: 5; последнее сообщение — 2 апреля 2012, 13:47; участников в обсуждении: 2.
|
min@y™ (статус: Доктор наук), 2 апреля 2012, 11:35 [#1]:
Чо тут сложного? Берём апрель 2012...
2 9 16 23 30
3 10 17 24
4 11 18 25
5 12 19 26
6 13 20 27
7 14 21 28
1 8 15 22 29
В апреле 30 дней. Выкидываем выходные с праздниками: 1, 7, 8, 14, 15, 21, 22, 29, 30. Остаётся 21 рабочий день. Умножаем на 8 часов, получается 168.
TextEdit.Text:= IntToStr(8 * WorkDaysCount);
Вуаля!
В чём проблема-то?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
stales (статус: 1-ый класс), 2 апреля 2012, 11:57 [#2]:
Спасибо, попробую. Может еще есть какие предложения у кого?
|
|
stales (статус: 1-ый класс), 2 апреля 2012, 12:09 [#3]:
Не совсем понятно, как программным путем откинуть выходные дни и оставить 21 рабочий? Подробный код бы реализации данного расчета.
|
|
min@y™ (статус: Доктор наук), 2 апреля 2012, 13:12 [#4]:
Цитата (stales):
Не совсем понятно, как программным путем откинуть выходные дни и оставить 21 рабочий?
Для этого программе нужны исходные данные, которые кем-то должны быть заданы, например, начальством. На разных предприятиях они могут быть разными, как ни крути. Я щас просто посмотрел на общезаводской календарь (его плановый отдел выпускает каждый год).
Если данные есть, то просто считай количество выходных и праздников и вычитай его из количества дней в месяце.
Цитата (stales):
как программным путем откинуть
Ну а как я тебе это объясню, если не знаю, каким макаром у тебя хранятся даты выходных и праздников?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
stales (статус: 1-ый класс), 2 апреля 2012, 13:47 [#5]:
Вот нашел похожий вопрос и там есть не большой исходник, но автор говорит, что не много не правильно он работает на некоторых месяцах. Может Вам удастся подправить его? Вот цитата оттуда:
---------
function Workday(d:TDate;c: byte = 5):Integer;
//c=5 если пятидневная рабочая неделя,
//если шестидневная - другое число
var f,l,wday:integer;
Year,Month,Day:Word;
s:TDate;
begin
DecodeDate(d,Year,Month,Day);
l:=DaysInMonth(d);
f:=1; wday:=1;
if c=5 then begin
repeat
s:=EncodeDate(Year,Month,f);
case DayOfWeek(s) of
1..5: wday:=wday+1;
end;
f:=f+1;
until
f=l;
end else begin
repeat
s:=EncodeDate(Year,Month,f);
case DayOfWeek(s) of
1..6: wday:=wday+1;
end;
f:=f+1;
until
f=l;
end;
result:=wday;
end;
вроде работает но вот в некоторых месяцах делет ошибку.
а использование следующим образом:
Label1.Caption:=IntToStr(Workday(fsDateTimePicker1.Date,5));
может у кого есть менее громозкий код, поделитесь.
--------------
|
4 апреля 2012, 11:20: Статус вопроса изменён на решённый (изменил автор вопроса — stales)
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|