学院仓库管理系统设计_第1页
学院仓库管理系统设计_第2页
学院仓库管理系统设计_第3页
学院仓库管理系统设计_第4页
学院仓库管理系统设计_第5页
已阅读5页,还剩85页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 HYPERLINK / 数据库课程设计报告题目:仓库治理系统组长:王 宁(P071513228)组员:胡乐乐(P071513227)徐 建(P071513237) 葛 东(P071513256) 张 超(P071513267)指导教师:曹永春计算机科学与信息工程学院仓库治理系统一、设计目标企业的仓库物资治理往往复杂、繁琐。本系统要紧针对企业生产所需要的各种设备而设计,实施验收入库并填写入库单和入库登记;企业各个部门依照所需要提出物质申请,打算员依照整个企业的需求开出物资设备出库单,仓库治理员依照出库单核对发放设备;设备使用完毕需要及时归还入库,填写还入库单。系统还依照需要按照月、季、年进行统

2、计分析,产生相应报表。依照系统功能的要求,仓库治理系统能够分为日志治理、入库、出库、还库、查询、报表等要紧模块。企业的物资供应治理往往是专门复杂、繁琐的。由于掌握的物资种类众多,订货、治理、发放的渠道各有差异,各个企业之间的治理机制不尽相同,各类统计打算报表繁多,因此物资治理必须实现计算机化,而且必须依照企业的具体情况制定相应的方案以便提高工作效率。依照当前的企业治理体制,一般物资供应治理系统,总是依照所掌握的物资类不,相应分成几个科室来进行物资的打算、订货、核销托收、验收入库。依照企业各个部门的来发送物资设备,并随时按期进行库存盘点、做台帐、依照企业自身领导和自身治理的需要按月、季、年进行统

3、计分析,产生相应的报表。为了加强相应物资、设备的治理,要定期掌握其储备、消耗情况,依照打算定额和实际消耗定额的比较,进行定额治理。仓库治理的物资在本章中要紧是企业生产所需的各种设备。进货时检查合同确认为有效托收之后,进行验收入库、填写入库单和入库登记。企业各个部门依照所需要的物资设备总额和部门生产活动所需要提出物资需求申请,打算员依照企业的需求开出物资设备出库单,仓库治理员依照出库单核对发放设备。设备使用完毕需要及时归还入库,填写还入库单。系统还依照需要按照月、季、年进行统计分析,产生相应报表。为了跟好的理解该系统和读明白该系统的源代码,读者应对以下的知识点有所了解:Access数据库操作的基

4、础知识。ODBC数据源基础知识。差不多的SQL语句,如添加、查询、修改和删除记录语句。Visual C+界面设计和关于数据库的基础知识。二、系统设计仓库治理的特点是信息处理量比较大,所治理的物资设备种类繁多,而且入库单、出库单、需求单等单据的发生量特不大,关联信息多,查询和统计的方式各不相同,在治理上实现起来有一定的困难。在治理的过程中经常出现信息的重复传递;单据、报表的种类繁多,各个部门治理规格不统一等问题。在本系统的设计过程中,为了克服这些困难,满足计算机治理的需要,采取了下面的一些原则:统一各种原始单据的格式,统一账目和报表的格式。删除不必要的治理冗余,实现治理规范化、科学化。程序代码标

5、准化,软件统一化,确保软件的可维护性和有用性。界面尽量简单化,做到有用、方便,尽量满足企业中不同层次职员的需要。建立操作日志,系统自动记录所进行的各种操作。1、系统功能分析 本例中的仓库治理系统需要完成的功能要紧有以下几点: 仓库治理各种信息的输入,包括入库、出库、还库、需求信息的输入等。 仓库治理各种信息的查询、修改和维护。 设备采购报表的生成。 在库存治理中加入最高储备和最低储备字段,对仓库中的物资设备实现监控和报警。 企业各部门的物资需求的治理。 操作日志的治理。 仓库治理系统的使用关心。2、系统功能模块设计 在系统功能分析的基础上,结合Visual C+程序编制的特点,得到如图1所示的

6、系统功能模块图。仓库治理系统仓库治理系统系统模块输入模块维护模块查看模块报表模块关心模块日志治理需求模块还库模块出库模块入库模块图1 系统功能模块图 系统要紧界面及流程如下所示。 程序开始运行之后先出现如图2的登陆界面。成功输入用户名和密码后将进入主对话框。图2 登陆界面单击“设备代码”按钮进入设备代码表(device_code)的治理。单击“库存信息”按钮进入现有库存表(device)的治理。单击“设备入库”按钮开始设备入库操作,若成功,则在设备入库表(device_in)中增加一条记录,同时修改现有的库存表(device)中的相关数据。单击“设备出库”按钮开始设备出库操作,如图3所示。若成

7、功,则在设备出库表(device)中的相关数据。 图3 设备出库登记窗口单击下方的“出库信息”按钮进入设备出库表(device_out)的治理。如图4所示。图4 出库信息治理界面单击“设备还库”按钮开始设备还库操作。若成功,则在设备还库表(device_return)中增加一条记录,同时修改现有库存表(device)中的相关数据。单击下方的“还库信息”按钮进入设备还库表(device_return)的治理。单击“设备需求”进入设备需求登记的界面,如图5所示。用户在那个地点填写设备需求。若成功,则在设备需求表(device_need)中增加一条设备需求记录。图5 设备需求登记窗口单击下方“需求信

8、息”按钮进入设备需求表(device_need)的治理。如图6所示。单击“操作日志”按钮查看目前的所有操作日志记录,在里面还能够删除所有日志记录。单击“关心”按钮进入联机关心。单击“关于”按钮查看程序信息图6 需求信息治理窗口三、数据库设计1、数据库需求分析在认真调查企仓库物资设备治理过程的基础上,得到本系统所处理的数据流程,如图7所示。 设备入库设备入库设备采购设备还库设备出库仓库现有库存各部门需求企业生产打算汇总图 7 数据流程图针对本实例,通过对企业仓库治理的内容和数据流程的分析,设计的数据项和数据结构如下:设备代码信息:其数据项有设备号、设备名称现有库存信息:其数据项有现有设备、现有数

9、目、总数目、最大库存和最小库存等设备使用信息:其数据项有使用的设备、使用部门、数目、使用时刻和出库时状态等设备采购信息:其数据项有采购的设备、采购员、供应商、采购数目和采购时刻等设备归还信息:其数据项归还设备、归还部门、归还数目、归还时刻和经手人等设备需求信息:其数据项有需求的部门、需求设备、需求数目和需求时刻等2、数据概念结构设计这一设计时期是在需求分析的基础上,设计出能满足用户需求的各种实体,以及它们之间的关系,为后面的逻辑结构设计打下基础。本实例依照上面得设计规划出实体有库存实体,入库实体、出库实体、采购实体、还库实体和需求实体。各实体的E-R图及其关系描述如下:现有库存现有库存现有库存

10、现有库存现有库存现有库存现有库存现有库存设备号入库入库供应商信息采购价格数量采购员设备号图9 入库实体E-R图出库出库使用部门数量、时刻经手人设备号图10 出库实体E-R图部门需求部门需求需求部门需求数量需求时刻设备号 图11 部门需求实体E-R图设备还库设备还库还库时刻人还库数量经手人设备号图12 还库实体E-R图打算采购打算采购库存信息供应信息时刻设备号 图13 打算采购实体E-R图入库入库 现有库存 出库 还库 部门需求设备采购图 14 实体和实体之间的关系E-R图3、数据库逻辑结构设计在上面的实体以及实体之间的关系的基础上,形成数据库中的表格和各个表格之间的关系。仓库治理系统数据库中的

11、各个表格的设计结果如下面的几个表格所示。每个表格表示在数据库中的一个表。 列名 数据类型 可否为空 讲明 CodeVARCHAR2(6) NOTNULL 设备号(主键) NameVARVHAR2(20) NULL 设备名称设备代码表device_code 列名 数据类型 可否为空 讲明CodeVARCHAR2(6)NOTNULL设备号In_dateDATENOTNULL入库时刻(主键)ProviderVARCHAR2(20)NULL供应商TelenoVARCHAR2(20)NULL供应商电话In_numberNUMBER(6)NULL入库数量PriceNUMBER(6)NULL价格BuyerV

12、ARCHAR2(10)NULL采购设备库表device_in列名 数据类型 可否为空 讲明CodeVARCHAR2(6)NOTNULL设备号DepartmentVARCHAR2(20)NULL使用部门Out_dateDATENULL出库时刻(主键)Out_stateNUMBER(1)NULL出库状况Out_personVARCHAR2(10)NULL经手人Out_numberNUMBER2(10)NOTNULL出库数量TakerVARCHAR2(10)NULL领取UsageVARCHAR2(20)NULL用途设备出库表device_out列名数据类型可否为空讲明codeVARCHAR2(6)N

13、OT NULL设备号(主键)now_numberNUMBER(6)NULL现有库存high_numberNUMBER(6)NULL最大库存low_numberNUMBER(6)NULL最小库存total_numberNUMBER(6)NULL总数现有数据库表device列名数据类型可否为空讲明codeVARCHAR2(6)NOT NULL设备号departmentVARCHAR2(20)NOT NULL部门名称need_numberNUMBER(6)NULL需要数量begin_dateDATENULL需求开始时刻end_dateDATEMULL需求结束时刻 设备需求表 device_need列

14、名数据类型可否为空讲明codeVARCHAR2(6)NOT NULL设备号return_dateDATENULL还库时刻(主键)keeperVARCHAR2(10)NULL仓库治理员return_numberNUMBER(6)NULL归还数量return_personVARCHAR2(10)NULL归还人 设备还库表device_return列名数据类型可否为空讲明do_userVARCHAR2(10)NOT NULL操作员do_whatVARCHAR2(40)NOT NULL操作内容do_dateDATENOT NULL操作时刻操作日志表howdo列名数据类型可否为空讲明codeVARCHA

15、R2(6)NOT NULL设备号now_numberNUMBER(6)NULL现有库存total_numberNUMBER(6)NULL总库存max_numberNUMBER(6)NULL购买数量providerVARCHAR(2)NULL供应商priceNUMBER(6)NULL价格buy_dateDATENULL打算采购时刻(主键)设备采购打算表 device_wantbuy4、数据库结构的实现 = 1 * GB3 创建设备代码device_codeCREATE TABLE “DMS”.device_code(code VARCHAR2(6) NULL,name VARCHAR2(20)

16、NULL,CONSTRANT code_code_pk PRIMARY KEY(code)TABLESPACE”USER_DATA”; = 2 * GB3 创建设备入库表 device_inCREATE TABLE “DMS”.device_in(code VARCHAR2(6) NOT NULL,in_date DATE NOT NULL,provider VARCHAR2(20) NULL,teleno VARCHAR2(10) NULL,in_number NUMBER(6) NULL,price NUMBER(6) NULL,buyer VARCHAR2(10) NULL,CONSTR

17、AINT in_date_pk PRIMARY KEY(in_date)TABLESPACE “USER_DATA”; = 3 * GB3 创建设备出库表 device_outCREATE TABLE “DMS”.device_out(code VARCHAR2(6) NOT NULL,department VARCHAR2(20) NULL,out_date DATE NULL,out_state NUMBER(1) NULL,out_penson VARCHAR2(20) NULL,out_number NUMBER(6) NOT NULL,taker VARCHAR2(10) NULL,

18、usage VARCHAR2(20) NULL,CONSTRAINT out_date_pk PRIMARY KEY(out_date)TABLESPACE”USER_DATA”; = 4 * GB3 创建现有库存表 deviceCREATETABLE ”DMS”.device(code VARCHAR2(6) NULL,now_number NUMBER(6) NULL,high_number NUMBER(6) NULL,low_ number NUMBER(6) NULL,total_ number NUMBER(6) NULL,CONSTRAINT device_code_pk PRI

19、MARY KEY(code)TABLESPACE”USER_DATA”; = 5 * GB3 创建部门需求表 device_needCREATE TABLE “DMS”,device_need(code VARCHAR2(10) NOT NULL,department VARCHAR2(10) NOT NULL,need_number NUMBER(6) NULL,begin_date DATE NULL,end_date DATE NULL,)TABLESPACE ”USER_DATA”; = 6 * GB3 创建设备还库表device_returnCREATE TABLE “DMS”,de

20、vice_return(code VARHAR2(6) NOT NULL,department VARCHAR2(20) NULL,return_date DATE NULL,keeper VARCHAR2(10) NULL,return_number NUMBER(6) NULL,return_person VARCHAR2(10) NULL,CONSTRAINT return_date_pk PRIMARY KEY (return_date)TABLESPACE ”USER_DATA”; = 7 * GB3 创建设备采购打算表 device_wantbuyCREATE TABLE “DMS

21、”,device_wantbuy(code VARCHAR2(10) NOT NULL,now_number NUMBER(6) NULL,total_ number NUMBER(6) NULL,max_ number NUMBER(6) NULL,buy_ number NUMBER(6) NULL,provider VARCHAR2(20) NULL,price NUMBER(6) NULL,buy_date DATE NULL,CONSTRAINT wantbuy_date_pk PRIMARY KEY (buy_date)TABLESPACE ”USER_DATA”; = 8 * G

22、B3 创建操作日志表 howdoCREATE TABLE “DMS”,howdo(do_user VARCHAR2(10) NOT NULL,do_what VARCHAR2(40) NOT NULL,do_date DATE NOT NULL,)TABLESPACE “USER_DATA”;四、系统实现1、创建应用程序此仓库系统应用程序的创建步骤如下: = 1 * GB2 、选择菜单“File|New”中的“新建项目”选项卡中“MFC AppWizard(exe)”,设置合适的目录和项目名,比如“E:Projects”目录下的“DMS”项目。 = 2 * GB2 、创建一个对话框应用程序(“

23、Dialog Based”),单击“Next”按钮。 = 3 * GB2 、由于在那个项目中将要使用ADO,因此在MFC AppWizard 的第2步,需要选中“Automation”选项,使应用程序能够支持自动化对象,如图15所示。图15 使应用程序支持自动化(Automation) = 4 * GB2 、单击“Finish”按钮,结束项目的创建。至此一个基于对话框的应用程序框架就搭建好了。主对话框名为CDMSDlg。 = 5 * GB2 、项目创建完毕之后,在头文件stdafx.h中加入下面4行:#importc:programfilescommonfilessystemadomsado1

24、5.dllno_namespace rename(EOF, adoEOF) #include icrsint.hinline void TESTHR(HRESULT x) if FAILED(x) _com_issue_error(x);#define DATEFMTCString(%s)第1行中的路径可能依照Visual Studio安装路径的不同而不同。其中的rename指令,把ADO中的EOF重命名为adoEOF,这是为了幸免和其他库的常量名冲突。注意第3行,那个地点定义了一个inline函数TESTHER,它的作用是测试COM函数的返回值,在那个返回值包含一个错误的时候,抛出一个_co

25、m_error型的异常。ADO作为一个COM组件接口,它的许多函数都会返回一个HRESULT型的值作为结果。假如在每一步都用SUCCEEDED或FAILED宏测试返回值的话,将会不胜其烦,还有可能制造出一连串嵌套的if语句如此不美观的代码。那个函数简化了这种验证操作,利用C+的异常处理机制,使代码显得紧凑而高效,为后面的工作带来专门大方便。第4行定义了一个宏。这是不同的后台数据库对SQL语句中日期的用法要求不同引起的。比如Access数据库要求SQL语句中的日期用两个#字符括起,而其他的数据库可能需要使用单引号或者双引号。因此在那个地点定义了那个DATEFMT宏,为了方便程序在不同的后台数据库

26、键切换。这是一个在开发的时候需要注意的细节,后面还会具体提到。2、COM知识预备下面介绍一些关于COM知识。这部分内容是针对那些没有学习过的COM技术的读者,目的是为他们理解ADO提供一些背景知识。COM技术在微软公司的应用中能够讲是无处不在,Windows系统相当多的服务都以这种方式提供,例如闻名的DirectX,还有在这一章中广泛应用的ADO。ADO的底层是OLE DB,他本身则是对OLE DB的一个COM包装。因此具备一些COM的知识,对使用ADO是专门有关心的,但并不是讲必须要精通COM才能使用ADO。事实上,在一般的应用中,只需要理解下面这段代码即可。/DlgViewReport.c

27、pp_RecordsetPtr pRst = NULL;IADORecordBinding *picRs = NULL; /Interface Pointer declared.(VC+ Extensions) CDevBuyRs rs;try_bstr_t strSQL(SELECT * FROM DEVICE_WANTBUY);TESTHR(pRst.CreateInstance(_uuidof(Recordset);pRst = m_DBCnt-Execute(strSQL, NULL, adCmdText); TESTHR(pRst-QueryInterface(_uuidof(IAD

28、ORecordBinding),(LPVOID*)&picRs);TESTHR(picRs-BindToRecordset(&rs);int i = 0;while (!pRst-adoEOF)m_list.InsertItem(0, rs.m_sz_code);m_list.SetItemText(i, 1, rs.m_sz_now);m_list.SetItemText(i, 2, rs.m_sz_total);m_list.SetItemText(i, 3, rs.m_sz_max);m_list.SetItemText(i, 4, rs.m_sz_buy);m_list.SetItem

29、Text(i, 5, rs.m_sz_provider);m_list.SetItemText(i, 6, rs.m_sz_price);m_list.SetItemText(i, 7, rs.m_sz_date);pRst-MoveNext(); picRs-Release();pRst-Close();catch(_com_error& e) AfxMessageBox(e.ErrorMessage();m_list.SetRedraw(TRUE);return; = 1 * GB3 、BSTR和_bstr_t下面的语句声明了一个_bstr_t型的变量,_bstr_t是对BSTR类型的一个

30、封装。_bstr_t strSQL(“SELETE *FROM DEVICE_WANTBUY”);关于BSTR,通俗地讲,它是COM中使用的字符串,与一般C程序中的字符串的区不在于:它一个带有字符计数值的字符串。它的字符计数值在字符数组的前面。它保存的在字符是所谓的“宽字符”(Wide character)。因此,关于一个BSTR而言,下面的语句确实是错的。BSTR str=L”Some words”;正确的做法是:Wchar_t st_=L”Some words”BSTR str;Bstr=SysAllocString(str_)释放一个SBSTR指针时,则调用SysFreeString函数

31、。每次都如此操控字符串未免太过苦恼,因此Visual C+ 里提供了_bstr_t那个类对BSTR做了封装,使程序员能够简单的对这种COM 字符串进行操作了。 = 2 * GB3 、IADORecordBinding和Iunkown一个COM组件包含了许多COM对象,程序员通过“接口”来操控这些对象,或者讲,这些对象通过提供给程序员的接口来实现自己的功能。下面这行代码中的IADORecordBind确实是一个指向这种接口的指针。IADORecordBingding *picRs=NULL; /Interface Pointer declared(VC+ Extension)每个接口差不多上从I

32、Unkown那个接口派生出来的。IUkown接口声明了3个纯虚函数:HRESULT QueryInterface(REFID rilid,void*ppvObject);ULONG AddRef();ULONG AddRef();一般来讲,不能直接拥有一个IADORecordBind或者IFoo、IBirdISomeInterface诸如此类的接口对象,程序员只能得到一个接口的指针,就像下面的这行代码:pRst-QueryInterface(_uuidof(IADORecordBingding),(LPVOID*)&picRs);这行代码解释了IUknown接口中QueryInterfae方法

33、的最差不多的用法:程序员用它来得到COM对象支持的某个接口的指针。如上例中,pRst时某一个COM对象提供的一个接口指针,程序员从某本书上(比如MSDN)明白了那个对象一定拥有一个IADORecordBinding型的接口,因此调用上面那行代码,得到了那个IADORecordBinding接口的指针。然后就能够使用IADORecordBinding接口里声明的那些方法了。如上所讲,一个COM对象,程序员往往不能直接拥有它的实例,而只是它的接口的指针。那什么时候来释放那个对象呢?这确实是AddRef和Release方法的用途。得到了一个接口指针,开始使用一个COM对象,就要调用它的AddRef方

34、法增加它内部的一个引用计数;使用完之后则调用Release方法减少那个计数。假如计数为零,则差不多讲明没有人使用,那个COM对象就会自己销毁自己。原则上讲,同一个对象提供的不同接口,AddRef和Release的效果差不多上一样的。因此在使用完一个COM接口指针之后,一定要如此:picRs-Release();假如忽略了这一句,就会造成一个COM对象及他所掌握的资源不能被正确释放。 = 3 * GB3 RecordsetPtr和智能指针如上一段所讲,使用完一个接口之后不记得调用Release是一件和糟糕的事,为了弥补这一点,就要写出一大串嵌套的if语句,降低了程序的易读性。程序就会抛出异常,而

35、程序员又没有写出捕获这种异常的代码(往往也不能写,谁也无法预料自己调用的某个库函数会跑出什么样的异常),如此也会跃过某个原本不想跃过的Release。如何解决那个问题呢?一种方法是用try_finally语句,然而由于现有编译器的缺陷,包含那个语句的代码编译出来的效率较低。这就用到了“智能指针那个工具。_RecordsetPtr pRs=NULL上面这行代码声明的变量确实是一个智能指针。从他的名字上看,他是对Recordset这种对象的指针进行了包装。TESTHr(pRst.CreateInstance(_uuidof(Recordset);这一句创建了一个Recordset型的COM对象,并

36、对智能指针赋值。在制作所在的函数体结束时,智能指针对象从栈中析构,在它的析构函数里调用了它所包含接口的Release方法。由它的工作原理看出,它解决了上面的问题栈中对象的析构函数不管如何差不多上会被调用的,即使函数发生了异常而退出的情况也是如此。除此之外,智能指针能够在接口指针赋值是自动调用AddRef方法这也是一个容易犯得错误。它通过重载运算符,使得它在使用时,和一般的接口指针毫无二致。3、操作日志模块的设计 = 1 * GB3 、写日志模块 通过操作日志模块,该系统每一次改变数据库数据的操作都会在操作日志表格中有相应的记录。如此能够增强操作人员的责任感,提高系统的安全性,也利于维护数据库数

37、据的完整性。此外,一个翔实的操作日志,也给开发过程中的调试、除错带来专门大便利,因此那个模块的设计被改在了最前面。先定义一个名为Clogmngr的类:/ LogMngr.h/定义一个Log治理器class CLogMngr public:CLogMngr();virtual CLogMngr();public:bool AddLog(LPCSTR op);void Setup(_ConnectionPtr cnnt, CString& user)m_DBCnt = cnnt;m_user = user;protected:_ConnectionPtr m_DBCnt;CString m_use

38、r;在那个类中,保存了一个数据库连接的指针m_DBCnt和当前用户的ID(m_user)。在主对话框CDMSDlg中加入了一个CLogMngr型的成员变量,并在CDMSDlg:OnInitDialog()中调用其Setup方法进行初始化,设置好数据库连接指针和用户名。如此当程序中某处需要写信息进行操作日志的时候,只需要调用那个类的AddLog方法即可。下面是CLogMngr:AddLog内部实现的详细过程。/LogMngr.cpp/向数据库中添加Log记录的代码bool CLogMngr:AddLog(LPCSTR op)CTime tm = CTime:GetCurrentTime();CS

39、tring sql_;sql_.Format(INSERT INTO HOWDO (do_user,do_what,do_date) VALUES(%s,%s,%d-%d-%d %d:%d:%d),m_user, op, tm.GetYear(), tm.GetMonth(), tm.GetDay(),tm.GetHour(), tm.GetMinute(), tm.GetSecond();_bstr_t sql = sql_;trym_DBCnt-Execute(sql,NULL,adCmdText);catch(_com_error& e) CString Error = e.ErrorM

40、essage(); AfxMessageBox(e.ErrorMessage();return false; return true;能够看到,它利用了Connection对象的Execute方法,直接执行SQL语句,向表中加入了一条包含了操作者、操作时刻和操作内容3个字段的记录。直接使用了SQL语句的方法在表比较简单的时候专门快捷,但在表包含比较多的字段的时候,就不太有用了。对日志表,我们暂且先用这种方法。 = 2 * GB3 、读日志模块在项目资源中加入一个对话框,它包含了一个列表框控件,几个编辑框和两个按钮。那个窗体用以显示系统所用的日志记录。它还将实现清空所有记录的功能(注意为了保证日

41、志记录的完整性、安全性,不能单独删除某条记录。)在删除所有记录时,用SQL语句显得专门方便。然而主意最好不要用那个“Delete * FROM HOWDO”如此的语句,而是使用下面的“TRUNCATETABLE”语句,它的速度比Delete快。/DlgViewLog.cpp/删除所有日志记录的函数void CDlgViewLog:OnBtnVlrmall() _bstr_t strSQL(TRUNCATE TABLE HOWDO);trym_DBCnt-Execute(strSQL,NULL,adCmdText);catch(_com_error& e) AfxMessageBox(e.Err

42、orMessage();EndDialog(0); RefreshData();此模块的时刻和数据处理与后面的类似,那个地点暂不叙述。最后整个船体的外表如图16所示。 图16 查看日志窗口4、登录窗口的设计在CDMSDlg:OnInitDialog()中加入如下一段代码:/DMSDlg.cpp/弹出登录界面CDlgLogIn dlg;doif (!dlg.DoModal()EndDialog(0); while (dlg.m_UsrName.GetLength()=0);它的目的是弹出图17所示的登录界面,并从中猎取一个有效的用户名。图17 登录界面在得到有效的用户名(字符串长度非0)后,程序

43、用如下的代码尝试连接数据库,初始化成员变量(Connection指针和ClogMngr的实例)。在连接成功后,写登录记录进入操作日志。/ DMSDlg.cpp/建立数据库连接,初始化成员变量/登录库,如失败,则关闭程序trym_DBCnt.CreateInstance(_uuidof(Connection);CString sql_;sql_.Format(DSN=DMS;UID=%s;PWD=%s,dlg.m_UsrName,dlg.m_UsrPwd);_bstr_t sql=sql_;m_DBCnt-Open(sql,-1);m_logMngr.Setup(m_DBCnt,dlg.m_Us

44、rName);m_logMngr.AddLog(登录数据库);catch(_com_error& e) AfxMessageBox(e.ErrorMessage();this-EndDialog(0); 最后不忘了在程序结束的时候关闭数据库连接。/ DMSDlg.cpp/void CDMSDlg:OnDestroy() CDialog:OnDestroy(); m_DBCnt-Close();5、主对话框的设计登录完成后,显示出主对话框。它的界面如图18所示,单击某个按钮就能弹出某个功能的界面。注意到按钮的排布时按照所处的模块分类的。 图18 主对话框界面 以其中“设备代码”按钮为例,讲明他的

45、事件处理函数。代码如下: /DMSDlg.cpp /显示设备代码治理界面 void CDMSDlg:OnBtnDevcode() CDlgDevcode dlg;dlg.Setup(m_DBCnt,&m_logMngr);this-ShowWindow(SW_HIDE);dlg.DoModal();this-ShowWindow(SW_SHOW);从上面的代码看出,当单击“设备代码”按钮时,程序构造一个CDlgDevcode型对话框实例,通过它的Setup函数赋给它一个数据库连接指针和一个日志治理对象实例的指针,然后主对话框隐藏,直到子对话框事物处理结束。6、设备代码治理窗口的建立设备代码表格

46、(device_code)经常被其他表格引用,如猎取合法编码、由设备编码号查找设备名称等。因此自日志模块和主对话框完成之后,先建立那个表格的治理模块。对话框类名为CDlgDevcode,设计如图19所示。图19 设备代码治理窗口那个地点用一个列表框控件显示读取的数据记录。在CDlgDevcode:OnInitDialog()中对那个控件(m_list)进行初始化(分割列、设置列宽、设置风格等)。/DlgDevcode.cpp/对话框的初始化BOOL CDlgDevcode:OnInitDialog() CDialog:OnInitDialog();m_list.InsertColumn(0,设

47、备号);m_list.InsertColumn(1,设备名);RECT rect;m_list.GetWindowRect(&rect);int wid = rect.right - rect.left;m_list.SetColumnWidth(0,wid/2);m_list.SetColumnWidth(1,wid/2);m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT);RefreshData();return TRUE;注意:其中一行代码:m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT),定义了当表格某整

48、行被选中时,将此行的完整数据在表格控件的右侧显示出来。以后的各个模块都用到了那个方法,这部分的代码如下:/DlgDevcode.cpp/消息映射部分BEGIN_MESSAGE_MAP(CDlgDevcode, CDialog)/AFX_MSG_MAP(CDlgDevcode) ON_NOTIFY(NM_CLICK,IDC_LIST_DEVCODE,OnClickListDevcode)/AFX_MSG_MAPEND_MESSAGE_MAP()/事件处理部分void CDlgDevcode:OnClickListDevcode(NMHDR* pNMHDR, LRESULT* pResult) i

49、nt i = m_list.GetSelectionMark();m_code = m_list.GetItemText(i,0);m_name = m_list.GetItemText(i,1);UpdateData(FALSE);*pResult = 0;其余程序清单/ / DlgDevcode.cpp : implementation file#include stdafx.h#include DMS.h#include DlgDevcode.h#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE

50、= _FILE_;#endif/ CDlgDevcode dialogCDlgDevcode:CDlgDevcode(CWnd* pParent /*=NULL*/): CDialog(CDlgDevcode:IDD, pParent)/AFX_DATA_INIT(CDlgDevcode)m_code = _T();m_name = _T();/AFX_DATA_INITm_DBCnt = NULL;m_log = NULL;void CDlgDevcode:DoDataExchange(CDataExchange* pDX)CDialog:DoDataExchange(pDX);/AFX_D

51、ATA_MAP(CDlgDevcode)DDX_Control(pDX, IDC_LIST_DEVCODE, m_list);DDX_Text(pDX, IDC_EDIT_DCCODE, m_code);DDX_Text(pDX, IDC_EDIT_DCNAME, m_name);/AFX_DATA_MAPBEGIN_MESSAGE_MAP(CDlgDevcode, CDialog)/AFX_MSG_MAP(CDlgDevcode)ON_NOTIFY(NM_CLICK, IDC_LIST_DEVCODE, OnClickListDevcode)ON_BN_CLICKED(IDC_BTN_DCA

52、DD, OnBtnDcadd)ON_BN_CLICKED(IDC_BTN_DCDEL, OnBtnDcdel)ON_BN_CLICKED(IDC_BTN_DCUPD, OnBtnDcupd)/AFX_MSG_MAPEND_MESSAGE_MAP()/ CDlgDevcode message handlersvoid CDlgDevcode:RefreshData()m_list.DeleteAllItems();m_list.SetRedraw(FALSE);_bstr_t strSQL(SELECT * FROM DEVICE_CODE);_RecordsetPtr MySet; int i

53、 = 0;tryMySet.CreateInstance(_uuidof(Recordset); MySet = m_DBCnt-Execute(strSQL,NULL,adCmdText);_variant_t Holder;while(!MySet-adoEOF) Holder = MySet-GetCollect(code);if(Holder.vt!=VT_NULL)m_list.InsertItem(i, (char*)(_bstr_t)Holder); Holder = MySet-GetCollect(name);if(Holder.vt!=VT_NULL)m_list.SetI

54、temText(i, 1, (char*)(_bstr_t)Holder);MySet-MoveNext(); catch(_com_error& e) AfxMessageBox(e.ErrorMessage();m_list.SetRedraw(TRUE);return; m_list.SetRedraw(TRUE);BOOL CDlgDevcode:OnInitDialog() CDialog:OnInitDialog();m_list.InsertColumn(0,设备号);m_list.InsertColumn(1,设备名);RECT rect;m_list.GetWindowRec

55、t(&rect);int wid = rect.right - rect.left;m_list.SetColumnWidth(0,wid/2);m_list.SetColumnWidth(1,wid/2);m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT);RefreshData();return TRUE; / return TRUE unless you set the focus to a control / EXCEPTION: OCX Property Pages should return FALSEvoid CDlgDevcode:OnC

56、lickListDevcode(NMHDR* pNMHDR, LRESULT* pResult) int i = m_list.GetSelectionMark();m_code = m_list.GetItemText(i,0);m_name = m_list.GetItemText(i,1);UpdateData(FALSE);*pResult = 0;void CDlgDevcode:OnBtnDcadd() UpdateData();CString sql_;sql_.Format(INSERT INTO DEVICE_CODE (code,name) VALUES(%s,%s), m

57、_code, m_name);_bstr_t sql = sql_;trym_DBCnt-Execute(sql,NULL,adCmdText);catch(_com_error& e) AfxMessageBox(e.ErrorMessage();return; m_log-AddLog(添加设备记录。); RefreshData(); void CDlgDevcode:OnBtnDcdel() UpdateData();CString sql_;sql_.Format(DELETE FROM DEVICE_CODE WHERE CODE=%s,m_code);_bstr_t sql = s

58、ql_;trym_DBCnt-Execute(sql,NULL,adCmdText); catch(_com_error& e) AfxMessageBox(e.ErrorMessage();return; m_log-AddLog(删除设备记录。); RefreshData(); void CDlgDevcode:OnBtnDcupd() UpdateData();CString sql_;sql_.Format(UPDATE DEVICE_CODE SET NAME=%s WHERE CODE=%s,m_name,m_code);_bstr_t sql = sql_;trym_DBCnt-

59、Execute(sql,NULL,adCmdText); catch(_com_error& e) AfxMessageBox(e.ErrorMessage();return; m_log-AddLog(更新设备记录。); RefreshData(); 由于那个表格比较简单,读者能够看出,里面所有的数据操作差不多上由SQL语句直接完成的,对数据的操控则通过VARIANT型变量进行,在此略微讲解一下VARIANT类型。VARIANT类型是COM技术中专门重要的一种数据类型,经常用于在组件之间传递类型不定的参数。它的定义如下:Typedef struct VARIANT VARTYPE vt; U

60、nsigned short wReserved1; Unsigned short wReserved2; Unsigned short wReserved3;Union Byte bVal; /VT_UI1 Short iVal;/VT_I2 LongIval;/VT_I4 Unsigned long FAR* pulVal; /VT_BYREF|VT_UI4 Int FAR * pintVal; /VT_BYRE|VT_INT Unsiged int FAR* puintVal; /VT_BYREF|VT_UINT 它实质上是一个结构体,第1个成员变量VT指明了VARIVAT当前包含的类型;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论