为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

基于VC++的考勤系统(论文)

2017-10-16 50页 doc 283KB 44阅读

用户头像

is_569018

暂无简介

举报
基于VC++的考勤系统(论文)基于VC++的考勤系统(论文) 基于VC++的考勤系统 摘要:随着现代科学技术的发展~越来越多的公司和企业对职工的考勤都实行了信息化管理~使用计算机系统代替复杂的手工方式来管理考勤事务。考勤系统可以有效地管理公司员工的出勤情况~规范人事制度管理~保证公司正常的工作~是人力资源管理的重要组成部分。因此~考勤管理系统的设计与实现有着十分重要的意义。 系统的开发主要包括后台数据库的建立~维护以及前端应用程序的开发两个方面~主要模块包括基本信息管理模块~考勤信息管理模块~统计查询模块和系统用户管理模块。系统是使用Visual C...
基于VC++的考勤系统(论文)
基于VC++的考勤系统(论文) 基于VC++的考勤系统 摘要:随着现代科学技术的发展~越来越多的公司和企业对职工的考勤都实行了信息化管理~使用计算机系统代替复杂的手工方式来管理考勤事务。考勤系统可以有效地管理公司员工的出勤情况~规范人事管理~保证公司正常的工作~是人力资源管理的重要组成部分。因此~考勤管理系统的与实现有着十分重要的意义。 系统的开发主要包括后台数据库的建立~维护以及前端应用程序的开发两个方面~主要模块包括基本信息管理模块~考勤信息管理模块~统计查询模块和系统用户管理模块。系统是使用Visual C++开发语言~使用Microsoft Visual Studio 6.0作为工具软件~数据库为Access 2003。系统采用目前比较流行的ODBC数据访问技术~并将每个数据库表的字段和操作封装到类中~它使应用程序的各个窗口都能够共享对表的操作~不需要重复编码~使程序更加易于维护~从而将面向对象的程序设计思想应用到数据库应用程序中。 关键字: Visual C++~Access~MFC~考勤管理~ODBC数据访问技术。 1 VC + + based on the attendance system Abstract:With the development of modern science and technology, an increasing number of companies and enterprises of the attendance of all employees to implement the information management, the use of complex computer systems to replace manual methods to manage time and attendance matters. Attendance system can effectively manage staff attendance and standardize the management of the personnel system to ensure that normal work is an important human resource management component. Therefore, the Attendance Management System Design and Implementation is very important. System mainly includes the establishment of the background database, front-end application maintenance and development of two main modules, including basic information management module, attendance information management module, statistics module and system queries the user management module. System is to use Visual C + + development language, the use of Microsoft Visual Studio 6.0 as a tool for software, database for Access 2003. System is currently more popular ODBC data access technology, and database tables for each of the field and operation of the class package, which allows applications to share all the various windows on the operation table, do not need to duplicate code, so that procedures more easy to maintain, so that object-oriented programming design concepts applied to database applications. Key words:Visual C + +, Access, MFC, attendance management, ODBC data access technology. 2 前 言 二十一世纪人类已进入到了一个高速发展的信息时代。社会的高度信息化要求各企事业单位不停的提高信息管理技术以适应社会的发展。 我国当前考勤管理在许多企业中还是停留在手工记录的方式~其操作相当繁杂。考勤工作需要管理者深入到企业的各个部门中去统计员工的出勤情况。由于企业部门繁多~导致经常会出现记录错误的情况发生。极大的影响了企业对员工的管理。本设计运用 Access 2003数据库设计软件与Visual C++程序语言设计了一个考勤管理软件。使用该软件~管理者可以快速记录公司全体员工当日的出勤状况。并可按月份统计员工出勤~出差~请假状况及正常工作时间。很好的解决了前者在管理方面所存在的弊端。且操作非常简单~用户只需要懂得操作Windows系统便可~无需再进行其他任何培训~方便用户使用。在本软件的开发过程中主要使用了Visual C++中的MFC库来完成用户界面设计和求值、统计的算法设计。运用 Access 2003来建立系统数据库~并通过ODBC实现两者的连接。 3 目 录 一 引 言 ........................................................ 5 (一) 课背景 ................................................. 5 (二) 本课题的研究意义 ......................................... 6 (三)本课题研究方法 ............................................ 6 二 开发工具 ......................................................... 6 (一) Visual C++ 6.0 ........................................... 6 (二) ACCESS 2003数据库 ........................................ 7 (三) ODBC数据访问技术 ......................................... 7 三 考勤系统的设计 ................................................... 9 (一) 需求分析 ................................................. 9 1 系统需求 ................................................... 9 2 功能需求 ................................................... 9 (二) 功能模块构成 ............................................ 10 (三) 数据库结构设计 .......................................... 10 四 考勤系统的实现 .................................................. 13 (一) 系统登录功能的实现 ...................................... 13 (二) 系统管理 ................................................ 14 (三) 考勤管理 ................................................ 14 1 加班信息管理 ............................................... 14 2 出差信息管理 ............................................... 15 请假信息管理 ............................................... 16 3 (四) 修改查询管理 ............................................ 16 1 添加修改 .................................................. 17 2 查询统计 .................................................. 17 (五) 系统设置 ................................................ 18 4 一 引 言 在当今社会~随着计算机的普及及网络技术的应用~考勤管理工作应该从繁琐的日常事务中解放出来~比工作效率。并且~使用计算机对员工信息进行考勤 查找方便、可靠性高)成管理~具有手工所无法比拟的优点。例如:查询迅速) 本低)高效率等。 ,一, 课题背景 长期以来~繁琐的考勤记录整理~统计~查询等工作~一直困扰着企业行政部门的工作人员。因此考勤管理在生产管理过程中充当着一个十分重要角色~考勤管理的效率对企业工作效率的提高起着举足轻重的作用。随着现代科学技术的发展~越来越多的公司和企业对职工的考勤管理都实行了信息化管理~使用计算机系统代替繁琐冗余的手工方式来管理考勤事务。基于此~开发了一套考勤管理系统~不仅能够很好的管理员工考勤信息~也能更好的提高企业的工作效率~并且这些信息也将直接作为公司对员工的奖惩、提升以及培训的一个重要依据。 ,二, 本课题的研究意义 随着计算机的普及和计算机科学技术的飞速发展~人们开始越来越多地利用计算机解决实际问题。考勤管理是商业信息管理的重要部分~面对大量的商品信息~采用人力处理将浪费大量的时间、人力和物力~而且统计数据麻烦。因此~开发一个界面友好~易于操作的考勤管理软件进行自动化处理变得十分重要~这正是本系统开发的目的和意义。通过此考勤管理系统的开发锻炼了学生的实际动手能力对以后的学习和工作能力的培养也具有重要意义。 ,三,本课题研究方法 开发考勤管理系统需要选择两种工具~即前台开发语言和后台数据库。一般开发C/S结构的应用程序时~前台开发语言通常可以选择Visual Basic、Visual C++、Delphi和Power Builder等~如果开发网络应用程序~则需要选择一个网络数据库系统~如Access、Oracle、 SQL Server 2000和IBM DB2等。本设计是使用Visual C++ 6.0的开发工具~使用Access 2003作为后台数据库开发~采用了比较流行的数据库访问技术ODBC(Open Database Connectivity),是提供对各种数据库的接口。本次毕业设计应首先分析考勤管理系统的相关功能~结合本次毕业设计的相关要求写出需求分析,其次~综合运用以前所学的相关知识~在设计中以需求分析为基础~写出系统开发计划、实现流程及相关问题的实现方法,同时~在开发设计与实现中~要保存好相关的设计文档。 5 二 开发工具 ,一, Visual C++ 6.0 Visual C++6.0 是微软公司1998年推出的产品~是基于Windows操作系统的编程工具~是Microsoft Visual Studio 6.0的组件之一~具有功能强大的可视化开发环境~为程序员开发软件提供了方便的条件~并且VisualC++6.0集程序的代码编辑、编译、连接、调试等功能与一体~给程序员提供一个完整、全面而又方便的开发环境。它采用一种巧妙的方法将Windows的编程复杂性封装起来~编程者可以比较轻松地进行Windows应用程序的设计。Visual C++ 6.0继承了以前版本的优点~为用户提供了更为友好的可视化开发环境。它提供了强大的编译能力以及良好的界面操作性~具有功能强大、通用性强和易于扩充等特点~越来越多的被用来当作客户/服务器应用程序的前台应用工具~而且能够对Windows NT、Windows 2000 以及Windows XP 下的C++程序设计提供完善的编程环境。同时Visual C++6.0 对网络、数据库等方面的编程也都提供相应的环境支持。随着可视化编程的蓬勃发展~越来越多的程序员开始使用可视化编程技术。 Visual C++6.0拥有两种编程方式: 一种是传统的基于WindowsAPI的C编程方式~虽然代码效率较高~但开发难度与开发工作量也随着增高~目前使用这种编程方式的用户已经很少。 另一种是基于MFC的C++编程方式~虽然代码运行效率相对较低~但开发难 C++开发windows应用度小~开发工作量小~源代码效率高~已经成为Visual 程序的主流。本系统选择的就是基于MFC的C++编程方式。 ,二, ACCESS 2003数据库 Access 2003是微软Office 2003系列软件的组件之一~是目前比较流行的、面向对象的中小型桌面关系型数据库系统软件。 Access 2003是一种关系式数据库~Access 2003数据库由七种对象组成~它们是表、查询、窗体、报表、宏、页和模块。 表(Table) ——表是数据库的基本对象~是创建其他5种对象的基础。表由记录组成~记录由字段组成~表用来存贮数据库的数据~故又称数据表。 查询(Query)——查询可以按索引快速查找到需要的记录~按要求筛选记录并能连接若干个表的字段组成新表。 窗体(Form)——窗体提供了一种方便的浏览、输入及更改数据的窗口。还可以创建子窗体显示相关联的表的内容。窗体也称表单。 报表(Report)——报表的功能是将数据库中的数据分类汇总~然后打印出来~以便分析。 宏(Macro)——宏相当于DOS中的批处理~用来自动执行一系列操作。Access列出了一些常用的操作供用户选择~使用起来十分方便。 模块(Module)——模块的功能与宏类似~但它定义的操作比宏更精细和复杂~用户可以根据自己的需要编写程序。模块使用Visual Basic编程。 页——是一种特殊的直接连接到数据库中数据的一种WEB页。通过数据访问 6 页将数据发布到Internet 或Intranet上~并可以适用浏览器进行数据的维护和操作。 ,三, ODBC数据访问技术 ODBC(Open Database Connectivity~开放数据库互连)是微软公司开放服务结构(WOSA~Windows Open Services Architecture)中有关数据库的一个组成部分~它建立了一组规范~并提供了一组对数据库访问的标准API,应用程序编程接口,。这些API利用SQL来完成其大部分任务。ODBC本身也提供了对SQL语言的支持~用户可以直接将SQL语句送给ODBC。 一个基于ODBC的应用程序对数据库的操作不依赖任何DBMS~不直接与DBMS打交道~所有的数据库操作由对应的DBMS的ODBC驱动程序完成。也就是说~不论是FoxPro、Access、SQL还是Oracle数据库~均可用ODBC API进行访问。 ODBC的体系结构由以下几个部分组成: ? 应用程序:就是我们使用ODBC访问数据库的应用系统 ? ODBC API:Windows提供的使用ODBC访问数据库的接口函数~应用程序 通过调用API中提供的函数~最终依靠SQL语句实现数据库的操作。 ? 驱动程序管理器,Driver Manager,:驱动程序管理器存放在ODBC32.DLL 中~它主要负责装载和卸载ODBC驱动程序~并将ODBC API函数的调用 转交给ODBC驱动程序。 ? 数据源:其中记录了应用程序要访问的数据库的一些信息~比如数据库 的位臵和名称、数据库的类型等。 ? ODBC驱动程序:是DBMS系统提供的使用ODBC进行数据库访问的驱动~ 也就是ODBC和数据库之间的接口~以DLL的形式提供。不同的数据库厂 商提供的驱动是不同的~也就是说~不能使用一种数据库的ODBC驱动来 访问另外一种数据库~比如不能使用SQL Server的ODBC驱动来访问 Oracle数据库。 ? ODBC数据源管理器,Administrator,:在Windows的控制面板中~我 们可以找到该程序~它主要管理已经安装的ODBC驱动程序~并管理数据 源,建立和删除等,。 各部件之间的关系如图下图所示: 7 图1 ODBC体系结构图 应用程序要访问一个数据库~首先必须用ODBC管理器注册一个数据源~管理器根据数据源提供的数据库位臵、数据库类型及ODBC驱动程序等信息~建立起ODBC与具体数据库的联系。这样~只要应用程序将数据源名提供给ODBC~ODBC就能建立起与相应数据库的连接。 在ODBC中~ODBCAPI不能直接访问数据库~必须通过驱动程序管理器与数据库交换信息。驱动程序管理器负责将应用程序对ODBCAPI的调用传递给正确的驱动程序~而驱动程序在执行完相应的操作后~将结果通过驱动程序管理器返回给应用程序。 在访问ODBC数据源时需要ODBC驱动程序的支持。用Visual C++6.0安装程序可以安装SQL Server、Access、Paradox、dBase、FoxPro、Excel、Oracle和Microsoft Text等驱动程序( 三 考勤系统的设计 ,一, 需求分析 1 系统需求 考勤管理系统需要满足:使用者通过计算机来管理每日工作的信息~对各个信息能进行及时的操作如删除、查询等。 8 2 功能需求 基于系统需求分析~该系统需要实现以下基本功能: ? 签到功能 这个功能是本系统的核心功能。当员工上班到公司后~通过输入自己的员 号然后进行某个操作~就可以把到达公司的时间记录下来~并且要求保存到数据库中~以备查询。 在记录下来的信息中应该包括员工的唯一号~以及签到的日期和签到的具体时间~这包括上班时间和下班时间的签到情况。 当然~这并不能全部反映员工出勤的情况~比如有些员工因为出差而不能签到~因为请假而不能签到等~因此对于当天不能按时签到的员工~需写明未签到原因~并将数据保存到数据库中~以备查询。 ? 查询功能 签到功能中要求将员工上班的签到情况记录下来~也就是供以后查看而用。 查询某个员工在某段时间或者某天的出勤情况~只要输入员工的唯一号码~并输入要查询的日期~即可将此员工在给定日期内的出勤情况显示出来。 ? 修改功能 对于出勤到公司的员工来说~通过签到即可将签到信息记录下来。可是对于因为某种原因不能到公司的员工来说~由于不能签到当天的出勤记录就没有。这样做对于公司的管理不利~应该把每位员工工作日的出勤情况记录下来~以备管理使用。另外~可能发生修改出勤结果的情况时~可能迟到是由于某种合理的理由时~可以到公司有关部门进行修改。 ? 系统配臵功能 要想考勤~必须确定合法的上班时间~对于不同的公司有着不同的规定~因此本系统将提供用户自行设定的功能。 自行设定的数据包括:上午上班时间、上午下班时间、下午上班时间和下午下班时间。 ? 员工维护 对于一个公司要考勤~显然是对属于这个公司的员工进行的~那么员工的信息就必须记录下来~包括员工的姓名、与昂共在这个公司的唯一员工号。 增加员工:当某个新人加入员工后~人事部分应该给他分配员工号~这样可以用此来签到~并且需要把此员工的信息增加到公司的员工信息库中。 删除员工:当某个员工离开这家公司后~应该把这个员工的信息删除~并且要求把他的所有的签到信息也删除。 修改员工信息:由于某种原因需要修改员工的信息~比如员工号重新分配~这时就需要提供修改功能~以便能够及时对员工信息的更新。 ? 用户登录 做为考勤系统来讲首先应该不是人人都可以进入的。因此~应该通过输入用户名和用户密码后再进入~并且要根据不同的权限进行功能提供方面的区分。 这里~要求分为两种权限的用户:一种是超级用户~一种是普通用户。 超级用户拥有系统提供的所有功能~包括“修改出勤”、“查询”、“员工维护”、“系统配臵”、“用户维护”、“签到”功能,而对于普通用户来说只有“签到”功能。 9 ,二, 功能模块构成 ? 系统登录:使用时输入用户名和密码进入考勤系统。 ? 系统管理:主要用于用户进入考勤系统后~可以选择重新登录或退出系统。 ? 考勤管理:主要用于员工非正常上班的情况下~做好统计记录~必备查询。 ? 修改查询管理:用于修改员工上班情况以及查询某个员工某个时间段的考勤情况。 ? 系统设臵:设定上下班时间~对于不同的企业~可以根据各自的规定~自行设定。 ,三, 数据库结构设计 根据用户的需求~对需要保存的信息进行分析~然后~设计出合理的表。下面是本系统数据库的设计。 为了运行程序的方便~本系统选择了Access 2003数据库。 数据库:Misdb.mdb 基于功能模块分析~为考勤系统创建16个数据表。其数据库的设计如下: 表3.3.1 考勤表,ATTENDANCE, 字段名称 字段数据类型 字段描述 PERSON 文本 员工号~唯一标志~外键 ID 数字 考勤统计编号 IN_OUT 文本 考勤出入类型 IO_TIME 日期/时间 上下班时间 要求:每个员工每天的出勤记录只有一条~因此员工号和出勤时间作为唯一标志。 外键:员工号必须在数据库表中已经存在。 表3.3.2 考勤统计表,ATTENDANCE_STAT, 字段名称 字段数据类型 字段描述 ID 数字 序列号 YEAR_MONTH 日期/时间 统计时间 PERSON 文本 员工号~外键 WORK_HOUR 数字 工作时间 OVER_HOUR 数字 加班时间 LEAVE_HDAY 文本 请假情况 ERRAND_HDAY 文本 出差情况 LATE_TIMES 数字 迟到次数 EARLY_TIMES 数字 早退次数 ABSENT_TIMES 数字 缺勤次数 表3.3.3 考勤记录表,COUNTER, 字段名称 字段数据类型 字段描述 ID 文本 考勤类型编号 10 COUNTER_VALUE 数字 次数统计 DESCRIPTION 文本 考勤类型 注:此表没有关键字。 表3.3.4 部门表,DEPARTMENT, 字段名称 字段数据类型 字段描述 ID 文本 部门简称 NAME 文本 部门名称 MANAGER 文本 部门经理 INTRO 文本 部门简介 注:此表没有关键字。 表3.3.5 教育水平表,EDU_LEVEL, 字段名称 字段数据类型 字段描述 CODE 数字 教育情况编号 DESCRIPTION 文本 学历 注:此表没有关键字。 表3.3.6 出差表,ERRAND, 字段名称 字段数据类型 字段描述 ID 数字 序列号 PERSON 文本 员工号~外键 START_TIME 日期/时间 开始时间 END_TIME 日期/时间 结束时间 DESCRIPTION 文本 出差情况描述 表3.3.7 岗位表,JOB, 字段名称 字段数据类型 字段描述 CODE 文本 职称简写 DESCRIPTION 文本 岗位描述 注:此表没有关键字。 表3.3.8 请假表,LEAVE, 字段名称 字段数据类型 字段描述 ID 数字 序列号 PERSON 文本 员工号~外键 START_TIME 日期/时间 开始时间 END_TIME 日期/时间 结束时间 REASON 文本 请假原因描述 表3.3.9 非正常工资类型表,OTHER_TYPE, 字段名称 字段数据类型 字段描述 CODE 数字 类型编号 DESCRIPTION 文本 非正常工资类型 注:此表没有关键字。 表3.3.10 加班表,OVERTIME, 字段名称 字段数据类型 字段描述 ID 数字 序列号 PERSON 文本 员工号~外键 11 WORK_HOURS 数字 加班时间 WORK_DATE 日期/时间 加班日期 表3.3.11 员工信息表,PERSON, 字段名称 字段数据类型 字段描述 ID 文本 员工号~唯一标志 PASSWD 文本 员工密码 AUTHORITY 数字 权限设臵 NAME 文本 员工姓名 SEX 文本 性别 BIRTHDAY 日期/时间 出生年月 DEPARTMENT 文本 部门简称 JOB 文本 岗位职称 EDU_LEVEL 文本 教育水平 SPECIALTY 文本 专业 ADDRESS 文本 地址 TEL 文本 联系方式 EMAIL 文本 电子邮箱 STATE 文本 工作状态 REMARK 文本 备注 关键字:ID 表3.3.12 员工,PERSONNEL, 字段名称 字段数据类型 字段描述 ID 数字 序列号 PERSON 文本 员工号 CHANGE 文本 变化 RECORD_TIME 日期/时间 记录时间 表3.3.13 员工变动表,PERSONNEL_CHANGE, 字段名称 字段数据类型 字段描述 CODE 数字 编号 DESCRIPTION 文本 描述 表3.3.14 工资表,SALARY, 字段名称 字段数据类型 字段描述 ID 数字 序列号 YEARMONTH 日期/时间 年月 PERSON 文本 员工名 BASIC 数字 基本工资 BONUS 数字 奖金 ADD_DETAIL 数字 加班费 ADD_TOTAL 数字 总共费用 SUB_DETAIL 数字 误工费 12 SUB_TOTAL 数字 减少统计 TOTAL 数字 总体统计 表3.3.15 福利奖金表,SALARY_OTHER, 字段名称 字段数据类型 字段描述 ID 数字 序列号 YEARMONTH 日期/时间 年月 PERSON 文本 员工号 TYPE 文本 类型 NAME 文本 员工姓名 MONEY 数字 工资 DESCRIPTIONL 文本 描述 表3.3.16 工资创建表,SALARY_SET, 字段名称 字段数据类型 字段描述 PERSON 文本 员工号 SALARY 数字 工资 此系统中将使用MFC ODBC进行编程~并用MFC提供的动态数据交换机制,record field exchange~RFX,~这将会给我们访问表中各个字段的值带来很大的方便~同时也方便系统升级为其他的数据库系统。 四 考勤系统的实现 ,一, 系统登录功能的实现 首先给出登录对话框~如图2所示: 图2 登录对话框 用户要使用本系统~首先必须通过系统的身份认证。如果用户名错误或者不存在~将无法进入系统。 13 ,二, 系统管理 系统管理功能包括:重新登录和退出系统。 如图3所示: 图3 系统管理 ,三, 考勤管理 考勤管理中负责对加班、出差和请假情况记录。 如图4所示: 图4 考勤管理 1 加班信息管理 加班信息管理主要是对加班员工的加班时间以及加班日期进行管理。包括添 加~删除加班信息。 如图5所示: 14 图5 加班信息管理 2 出差信息管理 出差信息管理主要是对出差员工信息进行管理。包括添加~查询~删除出差信息。信息包括出差时间、员工号、员工名称以及出差原因。 如图6所示: 15 图6 出差信息管理 3 请假信息管理 请假信息管理主要是对请假员工信息进行管理。包括添加~删除请假信息。信息包括请假时间、员工号、员工名称以及请假原因。 如图7所示: 图7 请假信息管理 ,四, 修改查询管理 修改查询管理包括添加修改和查询统计两个功能。 如图8所示: 16 图8 修改查询管理 1 添加修改 添加修改包括分别对全体员工的出勤情况进行添加~修改~删除。 如图9所示: 图9 添加修改 2 查询统计 查询统计功能可以对某个月某个时间段的全体员工出勤情况进行统计~并且能够查询单个员工当月出勤情况。 17 如图10所示: 图10 查询统计 ,五, 系统设臵 系统设臵主要对上下班时间进行设定~可以根据不同情况自行设定。 如图11所示: 图11 系统设臵 结论 经过一个学期的设计~“考勤信息管理系统” 已经基本设计完成。在这几个月的开发过程中~学到了许多有关数据库管理软件设计的东西。另外~通过对VC++6.0的使用~我也对软件有了一些认识~学到了很多关于该软件可视化编程 18 的东西,也深深体会到了VC++6.0的功能强大~使用和操作简单。基于该系统的一些设计~下面对系统做一个总结。 在整个设计过程中~主要的工作有: ? 系统的权限及安全设计~包括用户权限的个人设定~密码保护与修改。 ? 员工信息、出勤信息、员工工资、相关查询、密码修改、帮助说明和退出系统模块的页面设计及功能的设计实现。设计中力求界面友好、简洁~易于操作。代码部分尽量避免逻辑错误~算法设计简单合理~尽量使程序具有较好的可读性~有利于其他的设计者对程序的阅读。 ? 力求对数据库操作的安全与稳定~尽量避免数据库操作异常~并要保证查询的快速无误。 当然在设计中还有很多不足的地方。对于这样的软件开发~由于没有相应的切合实际的需求分析~所以在开发过程中遇到了许多棘手的问题。现在开发出来的软件对数据库的操作还不够稳定常会出现非法操作~异常处理做的还很欠缺。程序代码中还存在不少的Bug~这些在最后的测试过程中还有必要做较多的修改和完善。在设计时~由于时间和能力有限还有部分的功能没有实现~希望系统能在以后升级成更高版本时得以实现。 19 致 谢 在论文完成之际~我要特别感谢我的指导老师的热情关怀和悉心指导。在我撰写论文的过程中~老师倾注了大量的心血和汗水~无论是在论文的选题、构思和资料的收集方面~还是在论文的研究方法以及成文定稿方面~我都得到了杨婧 广博的学识、深厚的学术素养、严老师悉心细致的教诲和无私的帮助~特别是她 谨的治学精神和一丝不苟的工作作风使我终生受益~在此表示真诚地感谢和深深 的谢意。 在论文的写作过程中~也得到了许多同学的宝贵建议~在此一并致以诚挚的谢意。 感谢所有关心、支持、帮助过我的良师益友。 最后~向在百忙中抽出时间对本文进行评审并提出宝贵意见的各位专家表示衷心地感谢: 20 参考文献: 1? 刘瑞,吴跃进 ,王宗越. Visual C++项目开发实用案例. 科学出版社.2006 2? 孙鑫 余安萍. VC++深入详解. 电子工业出版社.2006 3? 陈清华等.Visual C++课程设计案例精选与编程指导.东南大学出版社.2004 4? 刘长明等.VISUAL C++实践与提高--多媒体篇 .中国铁道出版社.2003 5? 龙马工作室.VISUAL C++管理信息系统完整项目实例剖析.人民邮电出版社.2004 6? 訾秀玲等.Access数据库技术及应用教程. 清华大学出版社.2007 7? 李闽溟等 .Visual C++6.0数据库系统开发实例导航. 人民邮电出版社.2004 8? 严华峰等.VISUAL C++课程设计案例精编(第二版).中国水利水电出版社 2004 9? 张荣梅,梁晓林.Visual C++实用教程.冶金工业出版社.2004 10? 魏亮,李春葆编著.Visual C++程序设计例学与实践.清华大学出版社 .2006 21 附录: 部分代码如下: void CAttendanceDlg::OnAgainlogin() { // 隐藏主对话框 ShowWindow(SW_HIDE); // 显示登录对话框 CLoginDlg dlg; if(dlg.DoModal()==IDOK) { ShowWindow(SW_SHOW); // 显示对话框 } else EndDialog(IDCANCEL); // 退出程序 // TODO: Add your command handler code here } CAttDlg::CAttDlg(CWnd* pParent /*=NULL*/) : CDialog(CAttDlg::IDD, pParent) { // 设臵起始时间 CTime End_t=CTime::GetCurrentTime(); // 当前时间 CTimeSpan tp(30,0,0,0); // 时间间隔为30天 //{{AFX_DATA_INIT(CAttDlg) m_StartTime = End_t-tp; m_EndTime = End_t; m_strPersonID = _T(""); m_strName = _T(""); m_bSeekbyperson = FALSE; m_bSeekbytime = FALSE; //}}AFX_DATA_INIT } int CAttendanceApp::ExitInstance() { if(db.IsOpen()) db.Close();// 关闭数据库 return CWinApp::ExitInstance(); } // 全局函数~将时间串转换为CTime型变量 CTime StrToTime(CString str) {// 时间串格式 "%Y-%m-%d %H:%M:%S",如"1999-01-01 11:11:11" int nYear,nMonth,nDay,nHour,nMinute,nSecond; sscanf(str.Left(4), "%d", &nYear); // 得到年 sscanf(str.Mid(5,2), "%d", &nMonth); // 得到月 sscanf(str.Mid(8,2), "%d", &nDay); // 得到日 sscanf(str.Mid(11,2), "%d", &nHour); // 得到时 sscanf(str.Mid(14,2), "%d", &nMinute); // 得到分 22 sscanf(str.Mid(17,2), "%d", &nSecond); // 得到分 // 构造CTime变量 CTime result(nYear,nMonth,nDay,nHour,nMinute,nSecond); return result; } void CAttendanceDlg::OnBtnConfig() { // 显示工作时间设臵对话框 CWorkplanDlg dlg; dlg.DoModal(); } void CAttendanceDlg::OnBtnRecord() { // 非模态显示出勤记录对话框 if(!m_pAttDlg) // 指针为空~创建对话框 { m_pAttDlg=new CAttDlg(); m_pAttDlg->Create(IDD_DLG_ATTENDANCE, this); m_pAttDlg->ShowWindow(SW_SHOW); } else // 对话框已创建 m_pAttDlg->ShowWindow(SW_SHOW); // 显示窗口 } void CAttendanceDlg::OnBtnStatistics() { // 非模态显示考勤统计对话框 if(!m_pStatDlg) // 指针为空~创建对话框 { m_pStatDlg=new CStatDlg(); m_pStatDlg->Create(IDD_DLG_STAT, this); m_pStatDlg->ShowWindow(SW_SHOW); } else // 对话框已创建 m_pStatDlg->ShowWindow(SW_SHOW); // 显示窗口 } CAttendanceDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { pDC->SetBkMode(TRANSPARENT); // 设臵背景模式 return m_brush; // 返回画刷 } void CAttendanceDlg::OnAgainlogin() { // 隐藏主对话框 ShowWindow(SW_HIDE); 23 // 显示登录对话框 CLoginDlg dlg; if(dlg.DoModal()==IDOK) { ShowWindow(SW_SHOW); // 显示对话框 } else EndDialog(IDCANCEL); // 退出程序 // TODO: Add your command handler code here } BOOL CLoginDlg::OnInitDialog() { CDialog::OnInitDialog(); // 改变"登录人事管理系统"字体大小 LOGFONT LogFont; GetFont()->GetLogFont(&LogFont); LogFont.lfHeight+=LogFont.lfHeight/2; LogFont.lfWidth+=LogFont.lfWidth/2; m_font.CreateFontIndirect(&LogFont); GetDlgItem(IDC_STATIC_LOGINTEXT)->SetFont(&m_font); // 如数据库为打开状态~则关闭 if(db.IsOpen()) db.Close(); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CLoginDlg::OnOK() { BOOL bLogin=FALSE; CString strPasswd,strCount; UpdateData(); // 更新数据变量 if(!db.Open (m_strDSN)) return; // 连接数据库 strPasswd=CCrypt::Encrypt(m_strPasswd, 123); // 加密密码 CRecordset rs(&db); // 构造记录集 rs.Open(CRecordset::forwardOnly, "select COUNT(ID) as COUNT from PERSON where ID='" + m_strUser +"' and PASSWD='" + strPasswd + "' and AUTHORITY='4'"); // 执行查询 rs.GetFieldValue("COUNT",strCount); rs.Close(); // 关闭数据集 if(strCount=="1") // 判断认证是否通过 { EndDialog(IDOK); // 结束对话框~返回IDOK } else { 24 MessageBox("请确认用户名和密码,注意大小写!","认证失败"); db.Close(); // 关闭数据库 } } BOOL CPage1::OnInitDialog() { CDialog::OnInitDialog(); // 出入情况缺省为出 ((CButton*)GetDlgItem(IDC_RADIO_OUT))->SetCheck(TRUE); // 为List添加网格 m_cList.SetExtendedStyle(LVS_EX_GRIDLINES); m_cList.SetExtendedStyle(LVS_EX_FULLROWSELECT); // 设臵List的列 int nWidth=110; m_cList.InsertColumn(0, "记录编号", LVCFMT_LEFT, nWidth); m_cList.InsertColumn(1, "员工号", LVCFMT_LEFT, nWidth); m_cList.InsertColumn(2, "出入情况", LVCFMT_LEFT, nWidth); m_cList.InsertColumn(3, "时间", LVCFMT_LEFT, nWidth); CAttendanceRS rs(&db); // 构造出勤记录表 UpdateList(rs); // 更新List // TODO: Add extra initialization here return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CPage1::OnChangeEdtDepartid() { UpdateData(); // 更新数据 CDepartRS rs(&db); // 构造记录集 rs.m_strFilter = "ID='" + m_strDepartID + "'"; // 设臵过滤条件 rs.Open(); // 打开记录集 if(rs.GetRecordCount()==1) // 判断部门代码输入是否正确 { m_strDepartName=rs.m_NAME; // 提取部门名称 } else m_strDepartName.Empty(); // 清除部门名称 rs.Close(); // 关闭记录集 UpdateData(FALSE); // 更新界面数据 // TODO: If this is a RICHEDIT control, the control will not // send this notification unless you override the CDialog::OnInitDialog() // function and call CRichEditCtrl().SetEventMask() // with the ENM_CHANGE flag ORed into the mask. // TODO: Add your control notification handler code here } 25 void CPage1::OnChangeEdtPersonid() { UpdateData(); // 更新数据 CPersonRS rs(&db); // 构造PERSON记录表 rs.m_strFilter = "ID='" + m_strPersonID + "'"; // 设臵过滤条件 rs.Open(); // 打开记录表 if(rs.GetRecordCount()==1) // 判断员工号是否正确 { m_strPersonName=rs.m_NAME; // 提取员工姓名 m_strDepartID=rs.m_DEPARTMENT; // 提取员工所在部门编号 } else m_strPersonName.Empty(); // 清除员工姓名显示 rs.Close(); // 关闭记录表 UpdateData(FALSE); // 更新界面数据 OnChangeEdtDepartid(); // 显示部门名称 // TODO: If this is a RICHEDIT control, the control will not // send this notification unless you override the CDialog::OnInitDialog() // function and call CRichEditCtrl().SetEventMask() // with the ENM_CHANGE flag ORed into the mask. // TODO: Add your control notification handler code here } void CPage1::IO_Add(CString strPersonID) { int counter; // 用于计数 CString strIO; // 保存出入情况 CCounterRS rs_counter(&db); // 构造计数器记录表 // 记录编号 rs_counter.m_strFilter = "ID='A'"; // 设臵过滤器~提取计数值 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(); // 关闭计数器记录表 // 添加记录 // 判断确定出入情况 if(((CButton*)GetDlgItem(IDC_RADIO_OUT))->GetCheck()) strIO="O"; else strIO="I"; // 转换出入时间类型 int nYear,nMonth,nDay,nHour,nMinute; // 年,月,日,时,分 26 sscanf(m_strIOTime.Left(4), "%d", &nYear); // 得到年 sscanf(m_strIOTime.Mid(5,2), "%d", &nMonth); // 得到月 sscanf(m_strIOTime.Mid(8,2), "%d", &nDay); // 得到日 sscanf(m_strIOTime.Mid(11,2), "%d", &nHour); // 得到时 sscanf(m_strIOTime.Mid(14,2), "%d", &nMinute); // 得到分 // 得到出入时间 CTime IO_time(nYear,nMonth,nDay,nHour,nMinute,0); CAttendanceRS rs_attendance(&db); // 构造考勤记录表 rs_attendance.Open(); // 打开考勤记录表 rs_attendance.AddNew(); // 追加考勤记录 rs_attendance.m_ID=counter; rs_attendance.m_PERSON=strPersonID; rs_attendance.m_IN_OUT=strIO; rs_attendance.m_IO_TIME=IO_time; rs_attendance.Update(); rs_attendance.Close(); // 关闭考勤记录表 UpdateList(rs_attendance); // 更新列表框 } void CPage1::OnBtnAddperson() { if(!m_strPersonName.IsEmpty()) // 判断员工是否存在 { IO_Add(m_strPersonID); // 追加单个员工记录 } // TODO: Add your control notification handler code here } void CPage1::OnBtnAdddepart() { int i,n; // 用于保存记录条数 CPersonRS rs_person(&db); // 构造员工信息表 if(m_strDepartName.IsEmpty()) return; // 判断部门代号是否正确 // 设臵过滤条件 rs_person.m_strFilter="DEPARTMENT='"+m_strDepartID+"' and STATE='T'"; rs_person.Open(); // 打开员工信息表 n=rs_person.GetRecordCount(); // 获取员工人数 i=0; // 初始化已添加记录条数 // 初始化进度条 m_cProgress.SetRange(0, n); m_cProgress.SetPos(0); while(!rs_person.IsEOF()) // 对数据表中所有记录进行处理 { IO_Add(rs_person.m_ID); // 添加当前员工出勤记录 rs_person.MoveNext(); // 跳到下一个员工记录 m_cProgress.SetPos(++i); // 显示进度 27 } rs_person.Close(); // 关闭员工信息表 // TODO: Add your control notification handler code here } void CPage1::OnBtnAddall() { int i,n; // 用于保存记录条数 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()) // 对数据表中所有记录进行处理 { IO_Add(rs_person.m_ID); // 添加当前员工出勤记录 rs_person.MoveNext(); // 跳到下一个员工记录 m_cProgress.SetPos(++i); // 显示进度 } rs_person.Close(); // 关闭员工信息表 // TODO: Add your control notification handler code here } void CPage1::OnBtnDeleteattend() { CString strSQL; int nItem; // 得到第一个被选择Item的位臵 POSITION pos = m_cList.GetFirstSelectedItemPosition(); if(pos==NULL) { AfxMessageBox("没有选择记录!"); return; } while(pos) // 遍历所有被选Item { nItem=m_cList.GetNextSelectedItem(pos); // 得到Item Index // 构造SQL语句 strSQL="delete from ATTENDANCE where ID=" + m_cList.GetItemText(nItem, 0); db.ExecuteSQL(strSQL); // 执行 } 28 CAttendanceRS rs(&db); // 构造出勤记录表 UpdateList(rs); // 更新列表框 // TODO: Add your control notification handler code here } void CPage1::UpdateList(CAttendanceRS &rs) { int i=0; CString strID,strTime; rs.Open(); // 打开出勤记录表 m_cList.DeleteAllItems(); // 清除列表框内容 while(!rs.IsEOF()) // 对数据表中所有记录进行处理 { m_cList.InsertItem(i, ""); // 添加新Item strID.Format("%d", rs.m_ID); // 转换为字符串 m_cList.SetItemText(i, 0, strID); m_cList.SetItemText(i, 1, rs.m_PERSON); m_cList.SetItemText(i, 2, rs.m_IN_OUT); m_cList.SetItemText(i, 3, rs.m_IO_TIME.Format("%Y-%m-%d %H:%M")); rs.MoveNext(); // 跳到下一条记录 i++; } rs.Close(); // 关闭出勤记录表 } BOOL CPage2::OnInitDialog() { CDialog::OnInitDialog(); // 为List添加网格 m_cList.SetExtendedStyle(LVS_EX_GRIDLINES); m_cList.SetExtendedStyle(LVS_EX_FULLROWSELECT); // 设臵List的列 int nWidth=110; m_cList.InsertColumn(0, "记录编号", LVCFMT_LEFT, nWidth); m_cList.InsertColumn(1, "员工号", LVCFMT_LEFT, nWidth); m_cList.InsertColumn(2, "加班时间", LVCFMT_LEFT, nWidth); m_cList.InsertColumn(3, "加班日期", LVCFMT_LEFT, nWidth); COvertimeRS rs(&db); // 构造加班记录表 UpdateList(rs); // 更新List return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CPage3::UpdateList(CLeaveRS &rs) { int i=0; 29 CString strID,strSTime,strETime; rs.Open(); // 打开加班记录表 m_cList.DeleteAllItems(); // 清除列表框内容 while(!rs.IsEOF()) // 对数据表中所有记录进行处理 { m_cList.InsertItem(i, ""); // 添加新Item strID.Format("%d", rs.m_ID); // 转换为字符串 m_cList.SetItemText(i, 0, strID); m_cList.SetItemText(i, 1, rs.m_PERSON); strSTime=rs.m_START_TIME.Format("%y-%m-%d %H:%M"); m_cList.SetItemText(i, 2, strSTime); strETime=rs.m_END_TIME.Format("%y-%m-%d %H:%M"); m_cList.SetItemText(i, 3, strETime); m_cList.SetItemText(i, 4, rs.m_REASON); rs.MoveNext(); // 跳到下一条记录 i++; } rs.Close(); // 关闭记录表 } BOOL CPage4::OnInitDialog() { CDialog::OnInitDialog(); // 为List添加网格 m_cList.SetExtendedStyle(LVS_EX_GRIDLINES); m_cList.SetExtendedStyle(LVS_EX_FULLROWSELECT); // 设臵List的列 int nWidth=90; m_cList.InsertColumn(0, "记录编号", LVCFMT_LEFT, nWidth-20); m_cList.InsertColumn(1, "员工号", LVCFMT_LEFT, nWidth-20); m_cList.InsertColumn(2, "开始时间", LVCFMT_LEFT, nWidth+20); m_cList.InsertColumn(3, "结束时间", LVCFMT_LEFT, nWidth+20); m_cList.InsertColumn(4, "具体描述", LVCFMT_LEFT, nWidth); CErrandRS rs(&db); // 构造出差记录表 UpdateList(rs); // 更新List return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CPage4::UpdateList(CErrandRS &rs) { int i=0; CString strID,strSTime,strETime; rs.Open(); // 打开出差记录表 m_cList.DeleteAllItems(); // 清除列表框内容 while(!rs.IsEOF()) // 对数据表中所有记录进行处理 30 { m_cList.InsertItem(i, ""); // 添加新Item strID.Format("%d", rs.m_ID); // 转换为字符串 m_cList.SetItemText(i, 0, strID); m_cList.SetItemText(i, 1, rs.m_PERSON); strSTime=rs.m_START_TIME.Format("%y-%m-%d %H:%M"); m_cList.SetItemText(i, 2, strSTime); strETime=rs.m_END_TIME.Format("%y-%m-%d %H:%M"); m_cList.SetItemText(i, 3, strETime); m_cList.SetItemText(i, 4, rs.m_DESCRIPTION); rs.MoveNext(); // 跳到下一条记录 i++; } rs.Close(); // 关闭出差记录表 } BOOL CStatDlg::OnInitDialog() { CDialog::OnInitDialog(); // 为List添加网格 m_cList.SetExtendedStyle(LVS_EX_GRIDLINES); // 设臵List的列 int nWidth=100; m_cList.InsertColumn(0, "记录编号", LVCFMT_LEFT, 80); m_cList.InsertColumn(1, "员工号", LVCFMT_LEFT, 50); m_cList.InsertColumn(2, "年月", LVCFMT_LEFT, nWidth); m_cList.InsertColumn(3, "正常工作时间(小时)", LVCFMT_LEFT, nWidth+40); m_cList.InsertColumn(4, "加班时间(小时)", LVCFMT_LEFT, nWidth); m_cList.InsertColumn(5, "请假时间(半天)", LVCFMT_LEFT, nWidth); m_cList.InsertColumn(6, "出差时间(半天)", LVCFMT_LEFT, nWidth); m_cList.InsertColumn(7, "迟到次数", LVCFMT_LEFT, nWidth-30); m_cList.InsertColumn(8, "早退次数", LVCFMT_LEFT, nWidth-30); m_cList.InsertColumn(9, "旷工次数", LVCFMT_LEFT, nWidth-30); CStatRS rs(&db); // 构造出勤记录表 UpdateList(rs); // 更新List return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CStatDlg::UpdateList(CStatRS& rs) { int i=0; CString str; rs.Open(); // 打开统计数据表 m_cList.DeleteAllItems(); // 清除列表框内容 while(!rs.IsEOF()) // 对数据表中所有记录进行处理 31 { m_cList.InsertItem(i, ""); // 添加新Item str.Format("%d", rs.m_ID); // 转换为字符串 m_cList.SetItemText(i, 0, str); m_cList.SetItemText(i, 1, rs.m_PERSON); m_cList.SetItemText(i, 2, rs.m_YEAR_MONTH); str.Format("%d", rs.m_WORK_HOUR); m_cList.SetItemText(i, 3, str); str.Format("%d", rs.m_OVER_HOUR); m_cList.SetItemText(i, 4, str); str.Format("%d", rs.m_LEAVE_HDAY); m_cList.SetItemText(i, 5, str); str.Format("%d", rs.m_ERRAND_HDAY); m_cList.SetItemText(i, 6, str); str.Format("%d", rs.m_LATE_TIMES); m_cList.SetItemText(i, 7, str); str.Format("%d", rs.m_EARLY_TIMES); m_cList.SetItemText(i, 8, str); str.Format("%d", rs.m_ABSENT_TIMES); m_cList.SetItemText(i, 9, str); rs.MoveNext(); // 跳到下一条记录 i++; } rs.Close(); // 关闭统计数据表 } void CStatDlg::OnStatBtnStat() { CRecordset rs_Q_attend(&db); // 构造Q_attend记录集 CRecordset rs_Q_leave(&db); // 构造Q_leave记录集 CRecordset rs_Q_errand(&db); // 构造Q_errand记录集 CTimeSpan tp_1(1,0,0,0); // 构造一个1天的CTimeSpan CTimeSpan tp_02(0,2,0,0); // 构造一个2小时的CTimeSpan CTimeSpan TimeSpan[4]; // 保存上下班时间 int nHours[2]; // 保存上下午工作时间 CString strSTime,strETime; // 保存始末时间 CTime TimeStamp, LateTime, EarlyTime,WorkStart,WorkEnd; // 保存中间判断时间 int nWorkHour,nOverHour,nLeaveHDay,nErrandHDay; // 保存时间间隔长度 BOOL bLate,bEarly,bAbsent,bLeave,bErrand; // 保存判断结果 int nLateTimes,nEarlyTimes,nAbsentTimes; // 保存次数 CString cstr[4]; // 暂存起始时间 char str[4][9]; // 暂存起始时间 int i,j,n,counter; // 用于循环和计数 CString strTmp,strTmp1,strTmp2; // 临时变量 // 临时变量,年,月,日,时,分,秒 32 int nHour,nMinute,nSecond; CString strFileName=".\\workplan.ini"; // INI文件名 UpdateData(); // 更新数据 // 读取INI文件 GetPrivateProfileString("WorkPlan", "Time1", "08:00:00", str[0], 9, strFileName); GetPrivateProfileString("WorkPlan", "Time2", "12:00:00", str[1], 9, strFileName); GetPrivateProfileString("WorkPlan", "Time3", "14:00:00", str[2], 9, strFileName); GetPrivateProfileString("WorkPlan", "Time4", "18:00:00", str[3], 9, strFileName); for(i=0; i<4; i++) cstr[i]=str[i]; // 定义四个时间间隔变量并初始化为INI文件中的值 CTimeSpan *pTS; for(i=0; i<4; i++) { sscanf(cstr[i].Left(2), "%d", &nHour); // 得到时 sscanf(cstr[i].Mid(3,2), "%d", &nMinute); // 得到分 sscanf(cstr[i].Mid(6,2), "%d", &nSecond); // 得到秒 // 构造一个时间间隔变量 pTS=new CTimeSpan(0,nHour,nMinute,nSecond); TimeSpan[i]=*pTS; // 赋值 delete pTS; } nHours[0]=(TimeSpan[1]-TimeSpan[0]).GetTotalHours(); // 计算上午工作时间 if((TimeSpan[1]-TimeSpan[0]).GetMinutes()>30) nHours[0]++; // 四舍五入 nHours[1]=(TimeSpan[3]-TimeSpan[2]).GetTotalHours(); // 计算下午工作时间 if((TimeSpan[3]-TimeSpan[2]).GetMinutes()>30) nHours[1]++; // 四舍五入 // 转换统计开始时间 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()) // 依次对每个员工进行统计 { //获取出勤记录 33 // 执行查询 rs_Q_attend.Open(CRecordset::forwardOnly, "select IN_OUT,IO_TIME from ATTENDANCE\ where PERSON='" + rs_person.m_ID + "' and IO_TIME>" + strSTime + " and IO_TIME<" +strETime + " 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++) // 遍历班次 { 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); // 判断是否有出差记录 34 rs_Q_errand.Close(); // 关闭记录集 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)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) // 有记录 36 { // 提取加班时间 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; 37 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); // 更新列表框 } 38 39
/
本文档为【基于VC++的考勤系统(论文)】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索