📄 statdlg.cpp
字号:
strSTime=m_STime.Format("%Y-%m-%d");
// 转换统计结束时间,且天数加1
strETime=(m_ETime+tp_1).Format("%Y-%m-%d");
// 提取员工列表
CPersonRS rs_person(&db); // 构造员工表
rs_person.m_strFilter="STATE='T'"; // 设置过滤器,提取员工列表
rs_person.Open(); // 打开员工表
n=rs_person.GetRecordCount(); // 记录员工人数
i=0; // 初始化已处理员工人数
m_cProgress.SetRange(0,n); // 设置进度条
m_cProgress.SetPos(0); // 初始化进度条
while(!rs_person.IsEOF()) // 依次对每个员工进行统计
{
//获取出勤记录
// 执行查询
CString stringStime=strSTime;
CString stringEtime=strETime;
rs_Q_attend.Open(CRecordset::forwardOnly,
"select IN_OUT,IO_TIME from ATTENDANCE\
where PERSON='" + rs_person.m_ID
+ "' and IO_TIME>'" + stringStime
+ "' and IO_TIME<'" +stringEtime
+ "' order by IO_TIME");
strTmp1.Empty(); // 清空strTmp1
// 初始化
nWorkHour=nOverHour=0;
nLeaveHDay=nErrandHDay=0;
nLateTimes=nEarlyTimes=nAbsentTimes=0;
TimeStamp=m_STime; // 初始化时间戳为统计开始时间
while(TimeStamp < m_ETime+tp_02) // 判断是否超出统计结束时间
{
if(TimeStamp.GetDayOfWeek()!=1 &&
TimeStamp.GetDayOfWeek()!=7) // 判断是否工作日
{
for(j=0;j<=1;j++) // 遍历班次
{
rs_Q_attend.Close();
LateTime=TimeStamp+TimeSpan[2*j]; // 设置迟到时间
EarlyTime=TimeStamp+TimeSpan[2*j+1]; // 设置早退时间
// 判断是否请假
rs_Q_leave.Open(CRecordset::forwardOnly,
"select ID from LEAVE where\
PERSON='" + rs_person.m_ID
+ "' and START_TIME<'"
+ LateTime.Format("%Y-%m-%d %H:%M:%S")
+ "' and END_TIME>'"
+ EarlyTime.Format("%Y-%m-%d %H:%M:%S")
+ "'");
bLeave=(rs_Q_leave.GetRecordCount()>0); // 判断是否有请假记录
rs_Q_leave.Close(); // 关闭记录集
// 判断是否出差
rs_Q_errand.Open(CRecordset::forwardOnly,
"select ID from ERRAND where\
PERSON='" + rs_person.m_ID
+ "' and START_TIME<'"
+ LateTime.Format("%Y-%m-%d %H:%M:%S")
+ "' and END_TIME>'"
+ EarlyTime.Format("%Y-%m-%d %H:%M:%S")
+ "'");
bErrand=(rs_Q_errand.GetRecordCount()>0); // 判断是否有出差记录
rs_Q_errand.Close(); // 关闭记录集
rs_Q_attend.Open(CRecordset::forwardOnly,
"select IN_OUT,IO_TIME from ATTENDANCE\
where PERSON='" + rs_person.m_ID
+ "' and IO_TIME>'" + stringStime
+ "' and IO_TIME<'" +stringEtime
+ "' order by IO_TIME");
if(bLeave) // 如果有请假记录
nLeaveHDay++; // 请假记录加1
else if(bErrand) // 如果有出差记录
{
nErrandHDay++; // 出差计数加1
nWorkHour+=nHours[j]; // 按正常班累加工作时间
}
else // 正常上班
{
WorkStart=LateTime; // 设置工作开始时间
WorkEnd=EarlyTime; // 设置工作结束时间
bLate=TRUE; // 初始化迟到判断
bAbsent=FALSE; // 初始化旷工判断
// 判断是否迟到
if(!rs_Q_attend.IsEOF() && // 记录集不空
strTmp1.IsEmpty()) // 空,第一次GetFieldValue
rs_Q_attend.GetFieldValue("IO_TIME",strTmp1); // 得到IO_TIME
while(!rs_Q_attend.IsEOF()
&& StrToTime(strTmp1)<=LateTime)
{// 根据时间顺序判断是否迟到
// 得到IN_OUT
rs_Q_attend.GetFieldValue("IN_OUT",strTmp2);
bLate=(strTmp2=="O"); // 判断上班时间前是否报到
rs_Q_attend.MoveNext(); // 跳到下一条出勤记录
// 得到IO_TIME
if(!rs_Q_attend.IsEOF())
rs_Q_attend.GetFieldValue("IO_TIME",strTmp1);
}
// 判断是否旷工
if(bLate) // 判断是否迟到
{
if(!rs_Q_attend.IsEOF() && StrToTime(strTmp1)<EarlyTime)
WorkStart=StrToTime(strTmp1); // 记录迟到时间
else bAbsent=TRUE; // 如果下班前仍未报到记为旷工
}
bEarly=FALSE;
// 判断是否早退
while(!rs_Q_attend.IsEOF() && StrToTime(strTmp1)<EarlyTime)
{
// 得到IN_OUT
rs_Q_attend.GetFieldValue("IN_OUT",strTmp2);
bEarly=(strTmp2=="O"); // 判断是否有早退
if(bEarly)
{
// 将早退时间记录为工作结束时间
WorkEnd=StrToTime(strTmp1);
}
else WorkEnd=EarlyTime; // 将下班时间记录为工作结束时间
rs_Q_attend.MoveNext(); // 跳至下一条出勤记录
// 得到IO_TIME
if(!rs_Q_attend.IsEOF())
rs_Q_attend.GetFieldValue("IO_TIME",strTmp1);
}
// 如果旷工,增加旷工次数记录
if(bAbsent) nAbsentTimes++;
else
{
// 如果迟到,增加迟到次数记录
if(bLate) nLateTimes++;
// 如果早退,增加早退次数记录
if(bEarly) nEarlyTimes++;
// 计算实际工作时间
nWorkHour+=(WorkEnd-WorkStart).GetTotalHours();
if((WorkEnd-WorkStart).GetMinutes()>30)
nWorkHour++; // 四舍五入
}
}
} // End of 遍历班次
} // End of 是否工作日
TimeStamp+=tp_1; // 推进一天
} // End of TimeStamp < m_ETime+tp_02
rs_Q_attend.Close(); // 关闭Q_attend记录集
// 统计加班时间
CRecordset rs_Q_overtime(&db); // 构造Q_overtime记录集
rs_Q_overtime.Open(CRecordset::forwardOnly,
"select sum(WORK_HOURS) as SUM from OVERTIME\
where PERSON='" + rs_person.m_ID
+ "' and WORK_DATE>'"
+ m_STime.Format("%Y-%m-%d %H:%M:%S")
+ "' and WORK_DATE<'"
+ m_ETime.Format("%Y-%m-%d %H:%M:%S")
+ "'");
if(rs_Q_overtime.GetRecordCount()>0) // 有记录
{
// 提取加班时间
rs_Q_overtime.GetFieldValue("SUM",strTmp);
sscanf(strTmp,"%d",&nOverHour);
}
else nOverHour=0; // 无记录
rs_Q_overtime.Close();
// 判断是否已有该月考勤记录
CStatRS rs_stat(&db); // 构造统计数据表
// 设置过滤串
rs_stat.m_strFilter="PERSON='" + rs_person.m_ID
+ "' and YEAR_MONTH='" + m_strTime + "'";
rs_stat.Open(); // 打开数据表
if(rs_stat.GetRecordCount()==0) // 判断是否有该月份考勤记录
{
// 获取计数
CCounterRS rs_counter(&db); // 构造计数器表
rs_counter.m_strFilter = "ID='S'"; // 设置过滤器,提取计数值
rs_counter.Open(); // 打开计数器记录表
counter=rs_counter.m_COUNTER_VALUE; // 提取计数值
counter++; // 计数值加1
rs_counter.Edit(); // 编辑计数器
rs_counter.m_COUNTER_VALUE=counter; // 保存当前计数
rs_counter.Update(); // 提交修改
rs_counter.Close(); // 关闭计数器记录表
// 追加统计记录
rs_stat.AddNew();
rs_stat.m_ID=counter;
rs_stat.m_YEAR_MONTH=m_strTime;
rs_stat.m_PERSON=rs_person.m_ID;
rs_stat.m_WORK_HOUR=nWorkHour;
rs_stat.m_OVER_HOUR=nOverHour;
rs_stat.m_LEAVE_HDAY=nLeaveHDay;
rs_stat.m_ERRAND_HDAY=nErrandHDay;
rs_stat.m_LATE_TIMES=nLateTimes;
rs_stat.m_EARLY_TIMES=nEarlyTimes;
rs_stat.m_ABSENT_TIMES=nAbsentTimes;
rs_stat.Update(); // 提交修改
}
else
{
// 记录已存在修改数据
rs_stat.Edit();
rs_stat.m_WORK_HOUR=nWorkHour;
rs_stat.m_OVER_HOUR=nOverHour;
rs_stat.m_LEAVE_HDAY=nLeaveHDay;
rs_stat.m_ERRAND_HDAY=nErrandHDay;
rs_stat.m_LATE_TIMES=nLateTimes;
rs_stat.m_EARLY_TIMES=nEarlyTimes;
rs_stat.m_ABSENT_TIMES=nAbsentTimes;
rs_stat.Update(); // 提交修改
}
rs_stat.Close(); // 关闭数据表
i++; // 已统计员工数加1
m_cProgress.SetPos(i); // 显示统计进度
rs_person.MoveNext(); // 跳到下一个员工记录
}
rs_person.Close(); // 关闭员工表
CStatRS rs_stat(&db); // 构造统计数据表
UpdateList(rs_stat); // 更新列表框
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -