Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 6 041

/ вопрос решён /

Здравствуйте уважаемые эксперты! Как в Delphi вычислить количество рабочих часов в текущем месяце и занести результат, например, в компонет TextEdit, при условии, что: 5-ти дневная, 8-ми часовая рабочая неделя, два выходных: суббота, воскресенье. Если есть праздничные дни их тоже исключить из расчета рабочего времени. Если можно, приведите подробный пример. Заранее Спасибо!

stales Вопрос решён, но можно продолжить его обсуждение в мини-форуме

Вопрос задал: 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™

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

stales (статус: 1-ый класс), 2 апреля 2012, 11:57 [#2]:

Спасибо, попробую. Может еще есть какие предложения у кого?
stales

stales (статус: 1-ый класс), 2 апреля 2012, 12:09 [#3]:

Не совсем понятно, как программным путем откинуть выходные дни и оставить 21 рабочий? Подробный код бы реализации данного расчета.
min@y™

min@y™ (статус: Доктор наук), 2 апреля 2012, 13:12 [#4]:

Цитата (stales):

Не совсем понятно, как программным путем откинуть выходные дни и оставить 21 рабочий?

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

Цитата (stales):

как программным путем откинуть

Ну а как я тебе это объясню, если не знаю, каким макаром у тебя хранятся даты выходных и праздников?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
stales

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)

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 16:29
Выполнено за 0.03 сек.