东方之光ERP

 找回密码
 立即注册
搜索
查看: 6149|回复: 1
打印 上一主题 下一主题

[转载]考勤软件算法心得(含源代码)

[复制链接]

29

主题

77

帖子

143

积分

中级会员

Rank: 2

积分
143
跳转到指定楼层
楼主
发表于 2014-11-18 17:28:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
考勤软件算法
作者:大漠飞沙

    考勤软件的核心处理过程,是员工考勤数据与员工班次设置对比处理。

    我目前处理方式是:
    遍历所有的员工档案,若考勤类型为不需打卡的,直接跳过,不做处理;
    需要打卡的,首先找出该员工该日应出勤的班次,获取标准的打卡时间,然后查找考勤数据符合考勤规则的时间。如果是上班,则查找是否有允许提前打卡时间至迟到允许的范围内的时间点,若该时间点在迟到范围内,标记为迟到,该日迟到次数加一;如果是下班,则查找是否有早退允许的时间至下班可延迟打卡的范围内的时间点,如果有对应的时间点,就标记到标准数据对应的实际打卡时间中,如果时间点在早退范围内,则标记为迟到,该日早退次数加一;
    如无相应的时间点,则查找请假、调休、出差、替班等单据中,是否有相关时间范围内的记录,若有,标记相应的异常类型,然后算出该天的请假小时数、调休小时数、出差小时数、替班小时数、以上过程,获得日考虑报表。这个是考勤系统中最重要的一个报表,月报和年报都是在日报的基础上汇总得来的!

以下为处理过程流程图:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

29

主题

77

帖子

143

积分

中级会员

Rank: 2

积分
143
沙发
 楼主| 发表于 2014-11-18 17:31:03 | 只看该作者
[附源代码]

{  版权所有 (C) 2008 金星纸业有限公司     }

function TfrmKQDayReport.DayKQRPT(day: Tdatetime): boolean;
var
  i:integer;
  qryPerson:TAdodataset;
  SQL:string;
  BCName:string;
  KQDay:TKQday;
  StandTimeList:TstringList;
  FactTimeList:TStringList;
  ResultList:TStringList;
  AbnormityCode:integer;
  //异常的标志
  {0:无刷卡1:正常2:迟到3:早退}
  Flag:string;
  Minutes:integer;
begin
  //清除歷史資料
  SQL:='delete from tblKQDay where 日期=''' + datetimetostr(day) + ''''+'|';
  sysconfig.ExeSQL(SQL);
  //提取人事資料
  qryPerson:=TAdoDataset.Create(nil);
  sysconfig.OpenData(qryPerson,'select * from tblPerson');
  while not(qryperson.Eof) do
    begin
      case qryperson.FieldByName('考勤类型').AsInteger of
        1:begin //不需要打卡
            SQL:=format('insert into tblKQDay (日期,员工ID,状况,待处理) values(%f,%d,''%s'',%d)',
                        [day,qryperson.FieldByName('ID').AsInteger,'正常',0])+'|';
          end;
        0:begin
            BCName:=sysconfig.GetBCName(qryperson.FieldByName('公休顺延').AsBoolean,
                                        qryperson.fieldbyname('班次范围').AsString,
                                        qryperson.fieldbyname('周期起始日').AsDateTime,
                                        day);
            if BCName='公休日' then
              begin
                SQL:=format('insert into tblKQDay(日期,员工ID,状况,待处理) values(''%s'',%d,''%s'',%d)',
                        [DateTimeToStr(Day),qryperson.FieldByName('ID').AsInteger,'公休',0])+'|'   ;
                SysConfig.ExeSQL(SQL);
              end
            else
                begin
                   KqDay.day := day;
                   kqday.EmployeeID := qryperson.FieldByName('ID').AsInteger;
                   kqday.BCName := BCName;
                   kqday.standData := sysconfig.GetStandData(BCName,kqday.planHours);
                   KQDay.state := '正常';
                   Kqday.SKData := sysConfig.GetFactData(qryperson.fieldbyname('工卡号').AsString,day);
                   StandTimeList:=TStringList.Create;
                   FactTimeList:=TStringList.Create;
                   StandTimeList.Assign(sysconfig.DecomposeStr(kqday.standData));
                   FactTimeList.Assign(sysconfig.DecomposeStr(Kqday.SKData));
                   //TODO:如果考勤数据有遗漏(调休/请假/出差/替班/漏卡)
                   resultList:=SysConfig.AnalysisKQ(StandTimeList,FactTimeList);
                   for i:= 0 to ResultList.Count-1 do
                     begin
                       Flag:=LeftStr(ResultList.Strings,1);//0无刷卡1正常2迟到3早退
                       case StrToInt(Flag) of
                         0:if SysConfig.LoseCard(DateTimeToStr(KqDay.day),
                                                  Copy(StandTimeList.Strings,2,length(StandTimeList.Strings)-1),
                                                  KQDay.EmployeeID,kqday) then
                             begin
                              KQDay.bPend := true;
                              KQDay.state := '异常';
                             end
                           else
                              KQDay.state := '正常';
                         2:begin
                            KQDay.bLate := true;
                            KQDay.LateMinutes := StrToInt(Copy(ResultList.Strings,3,length(ResultList.Strings)-2));
                           end;
                         3:begin
                            KQDay.bLeaveEarly := true;
                            KQDay.LeaveearlyMinutes := StrToInt(Copy(ResultList.Strings,3,length(ResultList.Strings)-2));
                           end;
                       end;
                     end;
                    SavetoDataBase(KQDay);
                 end;

          end;
      end;
      qryperson.Next;
    end;
end;


回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表