关于请假情况下考勤班次的统计问题(100分)

  • 主题发起人 主题发起人 莫知
  • 开始时间 开始时间

莫知

Unregistered / Unconfirmed
GUEST, unregistred user!
在请假情况下如何根据请假的时间长短,来判断哪些班次要计算,哪些不需要计算
例如:
工人上班有三班,分别是7:30-12:30,14:00-18:00,19:00-22:00;
如果工人请假是一个时间段:7:30-12:30,那么这一个时段就不需进行计算,
如果工人请假不是一个时段:9:00-12:30,那么对这个不但要计算还要判断是否有迟到。
如果工人请假是7:30-18:00那么有两个班不用计算,而晚上的加班还是要计算
请问该如何判断,请给出部分源码以供参考,谢谢!
 
對於你的這個問題,我不是很清楚具體情況,我個人認呢,請假記錄應該有一個Table,
這個Table應該至少包含這麼幾個字段:1.個人id(EmplyeeID),2.開始日期(StartDate):TDate類型,
3.開始時間(StartTime):TTime類型,4.結束日期(EndDAte):TDate類型,
5.結束時間(EndTime):TTime類型.
這樣的話,就可以依據請假記錄來計算了.以一個班次為例:
if (Table1.FieldByName(StartTime).AsTime=StrToTime('07:30:00')) And
(Table1.FieldByName(EndDate).AsTime=StrToTime('12:20:00')) then
begin
.....//這個班次不需要計算
end else
begin
.....//這個班次需要計算
end;
 
这么简单的算法我早就想到了,但这个算法有个问题即在请假记录很多的情况下效率就
不是很理想了!
因此我想应该有个更好的算法,比如用几个SQL语句组合来实现,但我目前还没有找到
比较好的方法。
 
嘿!你在提问题啊!我来看看啊!
 
to taozhiyu:
是啊,真是巧啊!你有兴趣的话也帮忙讨论一下吧!
 
像這個考勤問題,我想應該是個本地數據庫,本地數據庫用SQL語句算法效率不是很理想.
況且實現比較困難,不過有個折衷的想法就是選查詢出符合條件的結果集,再用桌面數據庫
方法來處理.
 
考勤本来就 比较复杂,不清楚你的是否要先对员工排班,还有是否考虑重复打卡的情况。对了,你现在的做法是怎样的?
 
对于员工排班和重复打卡的情况我已经解决,现在关键是在请假的情况下如何知道哪些
班次要计算考勤哪些班次又不需要计算!难道要遍历所有班次来判断是否要计考勤吗?我认
为这个算法效率太低了!
不知各位有何好的意见和算法,请拿出来讨论!
 
我是这样想:不管请没请假,都要打卡,就是说要输入出入纪录,如果记录在工时外,就是
迟到或早退要看在不在假期内,在为false,否则为true。
 
实际上你问题可以这样描述一下:
if 工人在规定的时间内没有打卡(这称为考勤规则) then
begin
if 工人请假 then 请假原因
else
考勤结论(迟到,矿工,早退等)
end


也就是说,不管请没请假,都假设员工要打卡,只是他没打卡的时候才去判断请假没有,再
根据实际情况下结论
下面有个函数是判断请假情况的,你可以参考:
qjbt:请假表
dtstr:打卡日期
timstr:规定迟到的时间


function pandj(dtstr,timstr:string):string;//判断请假处理
var
qjbtime1,qjbtime2,qjbt1,qjbt2:string;
begin
{建议算法:增加一参数kahstr,用来传递卡号,判断是否请假时,先选出卡卡号为kahstr的记录,如果记录数为零,
则未请假,否则,比较请假时间再下结论}
//如果请假,按请假处理
dm.qjbt.first;
pandj:='';
while not dm.qjbt.eof do
begin
if dm.qjbt.fields[1].asstring=dm.rjl_temp.fields[0].asstring then
begin
qjbtime1:=copy(dm.qjbt.fields[2].asstring,5,4);//请假日期
qjbtime2:=copy(dm.qjbt.fields[3].asstring,5,4);
qjbt1:=copy(dm.qjbt.fields[2].asstring,9,4);//请假时分
qjbt2:=copy(dm.qjbt.fields[3].asstring,9,4);
if (copy(dtstr,5,4)>qjbtime1)and(copy(dtstr,5,4)<qjbtime2) then
begin//理论上打卡日期在请假日期范围内,(跨天假,不含当天)
pandj:=dm.qjbt.fields[4].asstring;//返回请假原因
exit;
end
else
begin
if (copy(dtstr,5,4)=qjbtime1) then
begin //只请了当天假 或在请跨天假的第一天
//判断半天
if (timstr<=qjbt2) then//理论上打卡时间内未打卡,则判断是否请了假
pandj:=dm.qjbt.fields[4].asstring //请了,返回请假原因
else
pandj:='旷工';
exit;
end
else
begin//在请跨天假的最后一天
if (copy(dtstr,5,4)=qjbtime2) then
begin
if (timstr<=qjbt2) then
pandj:=dm.qjbt.fields[4].asstring
else
pandj:='旷工';
exit;
end
else//未请假
begin
pandj:='旷工';
end;
end;
end;
end;
dm.qjbt.next;
end;
end;
 
我有这方面的商业软件
 
呵呵,我们公司的考勤软件是我一手开发的。我们是做门禁的公司,通过读感应卡的方式在
进出门的同时就实现了考勤依据的输入。
关于请假这方面,我们目前也只能做到对某个时段进行请假登记(还不能精确到小时),
觉得没必要。在登记请假记录的时候,今天的这个时间该你上班,那你请假呗;如果不该
你上班,你请什么假!!!
 
我的想法是:
每个人都应该有个排班记录。用一个表记录每个人每个月的排班记录。
这样当这个人请假输入电脑时,程序自动改此人的排班记录。
所以不管怎样,计算时只需判断每个人的考勤是否在排班记录内就可以了。
这样应该可以提高效率。
不知道我这样是否可以满足你的要求。
 
若是sql server的语法,可试试写个函数来实现:
1)函数创建脚本
--输入参数:请假起始时间,请假结束时间
CREATE FUNCTION [dbo].[Count1] (@StartTime DateTime, @EndTime DateTime)
RETURNS varchar(500) AS
BEGIN
declare @GBeginTime1 DateTime --早班起始时间
declare @GBeginTime2 DateTime --中班起始时间
declare @GBeginTime3 DateTime --晚班起始时间
declare @GEndTime1 DateTime --早班结束时间
declare @GEndTime2 DateTime --中班结束时间
declare @GEndTime3 DateTime --晚结束时间
declare @GroupName1 varchar(20)
Declare @GroupName2 varchar(20)
declare @GroupName3 varchar(20)
set @GBeginTime1='7:30'
set @GEndTime1='12:30'
set @GroupName1='7:30-12:30'
set @GBeginTime2='14:00'
set @GEndTime2='18:00'
set @GroupName2='14:00-18:00'
set @GBeginTime3='19:00'
set @GEndTime3='22:00'
set @GroupName3='19:00-22:00'
return
Case
when @StartTime>@GBeginTime1 and @EndTime<@GEndTime1 then @GroupName1+'工间离岗'
when @StartTime=@GBeginTime1 and @EndTime<@GEndTime1 then @GroupName1+'迟到'
when @StartTime=@GBeginTime1 and @EndTime>=@GEndTime1 then @GroupName1+'不计算'
when @StartTime>@GBeginTime1 and @EndTime>=@GEndTime1 and @StartTime<@GEndTime1 then @GroupName1+'早退'
else ''
end
+
Case
when @StartTime>@GBeginTime2 and @EndTime<@GEndTime2 then @GroupName2+'工间离岗'
when @StartTime<=@GBeginTime2 and @EndTime>@GBeginTime2 and @EndTime<@GEndTime2 then @GroupName2+'迟到'
when @StartTime<=@GBeginTime2 and @EndTime>=@GEndTime2 then @GroupName2+'不计算'
when @StartTime>@GBeginTime2 and @EndTime>=@GEndTime2 and @StartTime<@GEndTime2 then @GroupName2+'早退'
else ''
end
+
Case
when @StartTime>@GBeginTime3 and @EndTime<@GEndTime3 then @GroupName3+'工间离岗'
when @StartTime<=@GBeginTime3 and @EndTime>@GBeginTime3 and @EndTime<@GEndTime3 then @GroupName3+'迟到'
when @StartTime<=@GBeginTime3 and @EndTime>=@GEndTime3 then @GroupName3+'不计算'
when @StartTime>@GBeginTime3 and @EndTime>=@GEndTime3 then @GroupName3+'早退'
else ''
end

END
2)函数调用:
select dbo.Count1('15:00','20:00')
调用结果:14:00-18:00早退19:00-22:00迟到
 
to nywjx:
我做的这个企业是属于制造业的,它们是按工时来计算工资的,工人有时会请几个小时
的假出去办事然后又来上班的。所以除了按时段请假外还有这种方式!
llh_lily的思路比较符合我的问题,谢谢!
 
多人接受答案了。
 

Similar threads

D
回复
0
查看
957
DelphiTeacher的专栏
D
D
回复
0
查看
892
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
后退
顶部