面向连锁超市管理系统的分布式数据库设计与实现样本_第1页
面向连锁超市管理系统的分布式数据库设计与实现样本_第2页
面向连锁超市管理系统的分布式数据库设计与实现样本_第3页
面向连锁超市管理系统的分布式数据库设计与实现样本_第4页
面向连锁超市管理系统的分布式数据库设计与实现样本_第5页
已阅读5页,还剩83页未读 继续免费阅读

下载本文档

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

文档简介

分布式数据库课程设计与实现——面向连锁超市管理系统分布式数据库设计与实现目录1. 连锁超市管理系统概述 11.1 背景简介 11.2可行性分析 11.3系统目的和先进之处 21.4小构成员和任务分派 32. 需求分析 42.1顾客需求概述 42.2业务需求分析 52.3功能分析 63. 系统总体设计 83.1绘制用例图设计系统功能 83.2绘制系统流程图 93.3系统开发环境 103.4系统运营环境 113.5系统运营演示 113.6系统类库设计 144. 分布式数据库分析与设计 164.1数据库分析 164.2数据库概念设计 164.3数据库逻辑构造设计 204.4分片与位置分派设计 244.4.1站点通信模型 244.4.2数据表分片与位置分派设计 255. 基于SQLSMS详细设计(实现) 275.1公共类设计 275.1.1文献操作类CFileOperate 275.1.2时间格式转换类CMyTime 295.1.3数据操作类CADOConn 295.1.4数据库表操作类CtablePartInfo 375.2界面窗口设计 415.2.1系统启动登录开发 415.2.2主界面对话框设计 435.2.3通用报表对话框设计开发 445.2.4打印对话框设计开发 465.3基本资料模块设计 485.3.1基本资料管理功能开发 485.3.2价格自动生成功能开发 525.3.3报表功能实现 545.4进货/销售模块设计 555.4.1进货/销售登记设计 555.4.2进货设计 595.4.3月度记录设计 615.5库存模块设计 625.5.1库存查询功能开发 625.5.2库存报警功能开发 636. 开发技巧和难点分析 646.1OLE技术使用 646.2MFCGridControl控件使用 65连锁超市管理系统概述背景简介随着市场经济发展和人民生活水平提高,本来单一、小规模超市已无法满足人民对购物环境规定,大规模、物品丰富超市正在蓬勃发展。超市销售数据规模日益庞大,商品数目迅速增长,采用以往手工管理已直接或间接地减少了工作效率,最后影响超市寻常运转。此外超市发张壮大,特别是连锁超市(如家乐福、美廉美)扩张,使得她们具备地区上分散而管理上又相对集中特点,往往既要有各门店局部控制和分散管理,同步也要有整个组织全局控制和高层次协同管理。因而把这些门店和中心通过网络连接起来,设计开发一款基于分布式数据库连锁超市管理系统SMS(Supermarketmanagementsystem)势在必行。1.2可行性分析(1)经济可行性使用连锁超市管理系统对超市连锁店进行信息化管理将直接提高公司管理部门工作效率。通过网络远程提交汇总各门店信息,节约了许多时间和金钱。另一方面,用信息化管理记录大量数据,节约了诸多人力和财力,为管理者提供更好决策支持。(2)技术可行性网络应用基本设施完善,由于信息技术发展,国内计算机网络飞速发展,先后建成了中华人民共和国公众多媒体通信网、ChinaNet、中华人民共和国教诲与科研计算机网络等构成了中华人民共和国Internet主体,网络应用进入公司与普通家庭,这为发展连锁超市网络办公提供了基本设施。网络安全技术应用,涉及加密算法、CA数字认证、数字签名等,为网络办公系统应用提供安全保证,它实现了网络传播数据安全性、完整性等。最后,就是网络技术普及与掌握,如网络互联、网络安全技术、网络数据库技术等,使咱们有能力开发实现适合自己管理系统。因而,公司构建跨区域管理系统技术瓶颈问题(网络应用基本设施、网络安全、开发技术)得到了有效解决,公司构建网络管理系统技术上可行。(3)操作可行性由于SMS操作是基于C/S客户端页面操作,简朴明了,顾客无需学习,普通都可以很容易懂得如何操作。而管理员也无需具备专业知识,只需要对某些数据进行输入以及平时寻常维护就够了。1.3系统目的和先进之处(1)系统目的为连锁超市提高效率、减少成本;实现连锁超市管理优化,简化工作流程,节约人力物力,提高工作效率,极大地满足客户需要;对各环节进行控制分析,实现统一调度。满足连锁超市基本管理功能,发挥信息系统灵活性,减轻公司管理人员和操作人员工作承担,提高工作效率。本系统是一项功能比较完善连锁超市管理系统,对连锁店运作过程中后台数据可以随时进行分析,便于公司管理人员经营、决策。全面体现了当代公司管理理论所倡导工作高效、环境轻松氛围。(2)系统先进之处多数解决就地完毕。各地计算机由数据通信网络相联系。克服了中心数据库弱点:减少了数据传播代价。提高了系统可靠性,局部系统发生故障,其她某些还可继续工作。各个数据库位置是透明,以便系统扩充。为了协调节个系统事务活动,事务管理性能耗费高。1.4小构成员和任务分派2.1顾客需求概述下面是通过调查研究获得关于连锁超市重要信息数据需求分析成果:(1)连锁超市普通由一种中心(公司总部)、各种远程连锁店(门店)构成,并且每个连锁店分布在不同地区。(2)连锁超市各个部门之间、各个分店之间、分店与总部之间需要互换数据,这种数据互换是通过局域网和广域网进行。(3)公司总部负责产生并管理该连锁超市整体汇总数据,即各门店明细汇总表数据,如销售汇总表等。(4)每一种远程站点(各门店和公司总部)分别有一种数据库系统,各自构成一种独立子系统,可以分别独立进行本部门业务解决。(5)总部为了便于对各店进行管理,同步也为了比较各店销售状况,规定门店将所有商品归入相应商品类别,由总部统一管理并提供各门店使用,并且,商品类别信息数据在各门店都要经常使用。(6)关于商品信息、供应商信息、POS机信息、进货信息和销售信息等经营基本数据都是各门店单独管理和使用,门店之间互不有关。(7)整个连锁超市职工信息由公司总部管理和维护,各门店只可以查询本部门职工信息。2.2业务需求分析通过对超市营业、管理业务流程调查,得到下面业务需求。可以对商品类别、商品、供应商、POS机等基本信息进行管理。可以实现采购开单、销售开单、采购退货、销售退货等基本功能。软件可依照商品资料中设立最高库存、最低库存进行库存报警。商品批发价、零售价可自动生成,减轻定价工作量。可以生成各类记录报表,提供详尽营业报告,实现对商品进、销、存及利润等财务状况了如指掌。所有单据、报表均可以在打印前预览,并且可以导出为Excel文献,然后依照实际需要进行特别编排解决。为了系统安全,每次顾客登录都创立相应日记文献,记录顾客所有操作。此外,对系统性能重要有如下几种方面需求。系统在设计过程中应充分考虑到可扩充性,规定操作界面美观大方,容易上手。2.3功能分析依照对系统业务调查和顾客需求分析,结共计算机信息管理特点,设计系统实现功能如下。基本信息管理基本信息管理涉及业种商品类别信息、商品信息、供应商信息、POS机信息和价格信息维护与管理,实现功能涉及:基本信息添加、删除和更新操作。生成各类基本信息报表。打印和导出报表。进货管理进货管理重要实现对商品采购入库信息进行管理,详细实现功能如下:进货开单,实现商品进货结算、入库操作。进货退货,退还商家有关商品。生成进货、退货单据、商品报表。打印和导出报表。销售管理销售管理重要实现对商品销售出库有关信息进行管理,详细实现功能如下:销售开单,实现商品销售结算、出库操作。销售退货,容许客户退出有关商品。生成销售、销售退货单据、商品报表。打印和导出报表。库存管理库存管理重要实现对商品库存有关信息进行管理,详细实现功能如下:库存查询,可以查看所有库存商品有关信息。库存报警,对库存过多或过少商品进行报表记录。库存盘点,可以修改商品库存数量。帐务管理帐务管理重要实现对营业员销售商品、业务提成、营业收入等状况进行分类报表记录。数据管理数据管理重要实现对数据库数据进行备份、还原及清理等有关工作。系统管理系统管理重要实现登录顾客(职工)管理、系统日记、修改登录密码等有关工作。系统总体设计3.1绘制用例图设计系统功能用例图表达了角色和用例以及它们之间关系。它描述了系统、子系统和类一致功能集合,体现为系统和一种或各种外部交互者(角色)消息交互动作序列。也就是角色(顾客或外部系统)和系统(要设计系统)为了实现一种目交互,这个目描述普通是一种谓词短语,例如签合同等。系统设计包括超级管理员、管理员和营业员四种顾客角色。超级管理员具备所有操作权限,其用例图如图3-1所示。图3-1超级管理员角色系统用例图管理员不具备系统设立模块中顾客管理和商品类别信息管理功能,其她功能均具备。而销售人员则只具备销售开单管理功能。3.2绘制系统流程图结合系统详细设计规定,连锁超市管理系统重要功能流程图如图3-2所示。图3-2系统重要功能流程图系统一方面对登录顾客身份进行验证,依照顾客权限激活有关功能。超级管理员具备所有操作权限,系统功能构造图如图3-3所示。图3-3系统功能构造图上图只是列出了某些重要功能,系统还可以依照不同需求生成各种记录报表。3.3系统开发环境本系统是在WindowsXP中文版操作系统环境下,使用MicrosoftVisualStudio中文版用C++语言开发成功。在开发过程中,使用了OLE技术和ActiveX控件技术。后台数据库系统设计采用是MicrosoftSQLServer和Access数据库系统,通过ADO数据库开发技术,直接操作数据库文献。3.4系统运营环境系统可以直接在Win98、Win、WinXP环境下运营。系统预设超级管理员顾客名为“admin”,密码为“admin”。3.5系统运营演示程序启动,一方面弹出如图3-4所示“系统登录”对话框,只有输入对的顾客ID、登录密码才干进入系统可以。图3-4“系统登录”对话框如果登录顾客为超级管理员或管理员,会进入系统主界面窗口,如图3-5所示。图3-5系统主界面窗口如果登录顾客权限为营业员,由于其只具备售货权限,因而系统会直接弹出“销售开单”对话框,如图3-6所示。图3-6“销售开单”对话框在进行有关操作前,一方面需要添加、设立某些基本资料,如商品分类登记,其操作设立对话框,如图3-7所示。图3-7“商品分类登记”对话框此外,系统还提供了丰富报表功能,如图3-8所示商品分类报表,同步对报表提供了导出到Excel文献和打印功能。图3-8商品分类报表对话框3.6系统类库设计BITVRLab超市管理系统主框架设计是通过MFC创立向导创立基于对话框窗口程序,在对话框程序中添加了菜单栏,系统重要类库设计如下。自定义扩展类:为了提高开发效率、便于代码重用,自定义了某些数据操作类和控件扩展类,如表3-1所示。表3-1自定义扩展类及功能类说明CADOConn通过ADO实现对ACCESS、SqlServer等数据库访问CtablePartInfo依照数据库表分派、分片信息,实现对数据库表增、删、改、查CFileOperate实现对硬盘文献惯用操作CMyChiToLetter实现依照逐字提取中文拼音首字母CMyButtonCButton类派生类,实现带有位图和文本按钮CMyMenuCMenu类派生类,用于定制自己菜单CMenuItemContextCMenu类中用到此类,用于保存菜单项信息CMyTime实现简朴时间格式转换CMyExcel完毕VC对Excel文献操作对话框窗口类:在系统中,顾客所有数据查询、操作都是通过对话框窗口来实现,系统开发对话框类如表3-2所示。表3-2对话框类及阐明类说明CDlgFenJiBasePOS机基本信息管理对话框类CShopManageDlg主框架对话框类CDlgFenLeiBase商品分类基本信息管理对话框类CDlgDanganBase商品基本信息管理对话框类CDlgGongYingShangBase供应商基本信息管理对话框GDlgJiaGeSheZhi价格自动设立对话框类CDlgJinHuoKanDan商品进货开单管理对话框类CDlgJinHuoTuiDan商品进货退单管理对话框类CDlgXiaoShouKanDan商品销售开单管理对话框类CDlgXiaoShouTuiDan商品销售退单管理对话框类CDlgAll用于查找信息显示对话框类CDlgReport用于报表显示对话框类CDlgLogo顾客登录对话框类CDlgPwd更改密码对话框类CDlgQuit退出系统提示对话框类打印有关类:系统可以提供了报表打印和打印预览功能,其有关设计类如表3-3所示。表3-3打印有关类及阐明类说明CPrintFrameCFrameWnd派生类,用于构建打印框架类CPrintView打印视图类此外,系统还包括某些主框架有关类、导入ActiveX控件(MFCGridControl)有关类和导入OLE对象(Excel)有关类。分布式数据库分析与设计4.1数据库分析考虑到总站点信息量大采用SQLServer数据库,而区域站点信息量相对较小采用Access数据库。当区域业务拓展,操作终端增长时,Access数据库也很容易移植到SQLServer数据库系统中。此外区域站点采用Access数据库可以实现以便布置。4.2数据库概念设计分析超市管理功能流程,系统数据实体重要涉及基本资料对象实体、库存实体、进货/销售开单、进货/销售退单、进货/销售商品实体、各站点数据库服务器IP信息实体、数据库表分派分片信息实体等。基本资料对象实体涉及商品类别、商品明细、供应商、POS机和登录顾客实体。商品库存实体记录库存商品数量和价格信息,其实体E-R图如下。商品进货单实体用于记录进货单记录信息,其实体E-R图如下所示。进货商品实体用于记录进货单相应商品信息,其实体E-R图如下所示。进货退单实体用于记录进货退单信息,其实体E-R图如下所示。与进货相相应销售单实体、销售商品实体和销售退单实体E-R图如下所示。各站点数据库服务器IP信息,记录各个区域数据库服务器相应IP地址,其实体E-R图,如下图所示。数据库表分派分片信息,记录数据中所有表分布式分派和分片信息,其实体E-R图,如图所示。4.3数据库逻辑构造设计商品类别表、商品明细表、供应商表、POS机表、登录顾客表、库存表、进货/销售开单表、进货/销售商品表、进货/销售退货商品表、IP地址登录信息表、数据库表分派和分片信息。商品类别表:商品明细表:供应商表:POS机表:顾客表:库存表:进货单表:进货商品表:进货商品退单表:销售单表:销售商品表:销售商品退单表:服务器IP信息表:分片及分布信息表:4.4分片与位置分派设计4.4.1站点通信模型在咱们连锁超市管理系统中,有一种总店并下分各种分店,总店和分店之间或分店与分店之间都可以进行通信。每个分店是一种相对独立数据库服务系统,其可以连接任意数量客户端。通信模型如下图所示:4.4.2数据表分片与位置分派设计依照以上得到关于重要信息数据需求分析成果,为该连锁超市系统分布式数据库系统进行重要信息数据分片和分派设计如下:1、数据分片设计(1)由于该连锁超市系统各连锁店之间在经营上是独立,每个门店只关怀自己经营状况,关于供应商信息、POS机信息、商品信息和进货/销货信息等基本数据都是各门店单独管理和使用,门店之间互不有关。因而,商品明细表、供应商表、POS机表、库存表、进货/销售开单表、进货/销售商品表、进货/销售退货商品表按照地区(门店所在区域标志)采用水平分片办法得到水平片段。(2)这里咱们对于商品信息进行了垂直分片,提成了商品明细表和库存表,由于商品某些属性,例如库存量等需要经常更新,因而将这些属性划分出来构成单独实体可以减少系统开销。(3)由于整个连锁超市职工信息由总公司管理和维护,各门店只可以查询本店职工信息。因此职工信息不必分片,可以采用视图形式提供应各门店查询本门店职工信息。此外,各个区域数据库服务器IP地址信息也只是由总部管理、维护,因此也不必分片。(4)由于商品分类数据由总部统一管理并提供各门店使用,并且,商品类别信息数据在各门店都要经常使用。因而,商品类别信息数据也不必分片。(5)该分布式数据库系统实现了简朴目录管理,记录数据库中各个表分片和分派信息,以便数据更新时,维护各个站点上数据一致性。这个表由总部规划建立,各门店也会经常使用。因而,数据库目录信息表也不必分片。2、数据及其片段分派设计(1)对于只在各门店单独使用除商品类别信息和数据库目录信息以外其她基本信息片段,采用按区域分片然后分派到各个门店数据库服务器上。总站上有所有门店所有信息。(2)整个系统职工信息、IP地址信息由公司总部管理和维护,因此只分派在总部站点中。(3)商品类别信息、数据库目录信息是由总部统一规定并下发到各门店,由于各店经常会使用到此类基本信息,因而在各门店都具备相似副本。因此,商品类别信息、数据库目录信息都不会分片但被复制,且复制个数为门店个数。基于SQLSMS详细设计(实现)5.1公共类设计为了提高程序代码开发效率,便于代码重用,在系统开发中,创立了某些数据操作类和控件扩展类。5.1.1文献操作类CFileOperate为了便于对硬盘文献操作,开发了文献操作类CFileOperate,它通过调用API函数实现惯用文献操作。CFileOperate类声明代码如下。externCStringstrTmpPath;classCFileOperate{public: //构造函数 CFileOperate(); //获得当前程序运营途径 CStringGetAppPath(); //判断与否存在strFn文献夹 BOOLIsFileExist(CStringstrFn,BOOLbDir); //制作strFloderName文献夹返回文献夹名 CStringMakeDirectory(CStringstrFloderName); //自动生成文献夹 CStringMakeDirectory(); //得到文献夹名为strFloderName途径 CStringGetDirectoryPath(CStringstrFloderName); //删除strFloderdName文献夹 voiddelDirectory(CStringstrFloderdName); //删除主文献夹(data) voiddelMainDirectory(); //制作主文献夹 voidMakeMainDirectory(); //判断strIntDigit与否为整数,与否不大于intBig BOOLCheckIntDigit(CStringstrIntDigit,intintBig); //判断strFileName与否可以做文献夹或文献名字 BOOLCheckFileName(CStringstrFileName); //判断strText与否为空 BOOLCheckEmpty(CStringstrText); //删除strFloderName文献夹下名为strFileName文献 voiddelFile(CStringstrFloderName,CStringstrFileName); //得到strFloderName文献夹下名为strFileName文献途径 CStringGetFileName(CStringstrFolderName,CStringstrFileName); //制作strFloderName文献夹下名为strFileName文献 CStringMakeFile(CStringstrFloderName,BOOLblnMake); //显示文献夹对话框 BOOLGetFolder(CString*strSelectedFolder,constchar*lpszTitle,constHWNDhwndOwner,constchar*strRootFolder,constchar*strStartFolder);系统程序中重要用到了CFileOperate类中GetAppPath函数。GetAppPath函数用于获取当前运营程序所在文献夹途径,其实当代码如下。CStringCFileOperate::GetAppPath()//获得当前运营程序所在文献夹途径{ charlpFileName[MAX_PATH];//途径数组 //获取当前运营程序全途径 GetModuleFileName(AfxGetInstanceHandle(),lpFileName,MAX_PATH); CStringstrFileName=lpFileName; //从字符串最右边向左搜索'\\'串 intnIndex=strFileName.ReverseFind('\\'); CStringstrPath; if(nIndex>0) strPath=strFileName.Left(nIndex);//取'\\'串左边字符 else strPath=""; returnstrPath;//返回前运营程序文献夹途径}5.1.2时间格式转换类CMyTime系统开发中,需要频繁对日期、时间数据进行操作,因而这里设计了类CMyTime,实现简朴时间日期转换,CMyTime类声明如下。classCMyTime{public: CTimeValueTime;//CTime类型值 //blnChinese:TRUE-"年月日时分秒"FALSE-"-:" CStringGetAllString(BOOLblnChinese); //返回字符串形式日期时间 //blnChinese:TRUE-"年月日"FALSE-"-" CStringGetDateString(BOOLblnChinese);//返回字符串形式日期 //blnChinese:TRUE-"时分秒"FALSE-":" CStringGetTimeString(BOOLblnChinese);//返回字符串形式时间 CStringGetSimpleString();//返回简朴字符串形式日期时间 CStringGetWeek();//返回星期"星期日" //设立字符串形式值 //blnSimple:TRUE-(%Y%m%d%H%M%S)FALSE-(年月日时分秒或-:) voidSetAllString(CStringValue,BOOLblnSimple); voidSetNow();//设立成当前时间 CMyTime();//构造函数};SetNow函数获取当前日期,时间,将其值赋予ValueTime。voidCMyTime::SetNow(){ ValueTime=CTime::GetCurrentTime();}5.1.3数据操作类CADOConn系统开发了数据操作类CADOConn,它是本系统核心,实现了对数据库数据基本操作功能,CADOConn类声明代码如下。#import"c:\programfiles\commonfiles\system\ado\msado15.dll"\ no_namespacerename("EOF","adoEOF")classCADOConn{//定义变量public: _ConnectionPtrm_pConnection;//指向Connection对象指针: //添加一种指向Recordset对象指针: _RecordsetPtrm_pRecordset; _bstr_tm_strData; intm_DataType; CADOConn(intDataType);//构造函数 CADOConn(); virtual~CADOConn(); voidOnInitCADOConn();//初始化连接数据库 _RecordsetPtr&GetRecordSet(CStringstrSQL);//执行查询 BOOLExecuteSQL(CStringstrSQL);//执行SQL语句,InsertUpdatedelete voidExitConnect();//退出连接 BOOLMoveFirst();//字段集移向开头 BOOLMoveNext();//字段集向下移 BOOLOpen(CStringstrSQL);//打开记录集 BOOLOpenLogo(CStringstrSQL);//打开记录集 CStringGetValueString(intindex,intstrSum);//返回记录集中某字段字符串 byteGetValueByte(intindex);//返回记录集中某字段字节 intGetValueInt(intindex);//返回记录集中某字段短整数 doubleGetValueDouble(intindex);//返回记录集中某字段双精度数 floatGetValueFloat(intindex);//返回记录集中某字段单精度数 longGetValueLong(intindex);//返回记录集中某字段长整型数 CTimeGetValueDate(intindex);//返回记录集中某字段日期时间 //获取记录集某字段BYTE值,并换为CString返回 CStringGetValueByteStr(intindex,intstrSum); //获取记录集某字段INT值,并换为CString返回 CStringGetValueIntStr(intindex,intstrSum); //获取记录集某字段Double值,并换为CString返回 CStringGetValueDoubleStr(intindex,intstrLSum,intstrRSum); //获取记录集某字段Float值,并换为CString返回 CStringGetValueFloatStr(intindex,intstrLSum,intstrRSum); //获取记录集某字段Long值,并换为CString返回 CStringGetValueLongStr(intindex,intstrSum); //获取记录集某字段CTime值,并换为CString返回 CStringGetValueDateStr(intindex,CStringstrType); //添加单项数据 BOOLAddItem(CStringstrTable,intstrSum,LPCTSTRpszText,...); //得到字段中数据类型 intGetValueType(intindex); BOOLadoEOF();//记录集结束判断 BOOLFillList(CListCtrl*listMain,intColOpenEnd);//填充列表(ColOpenEnd代表展开多少列) BOOLInitList(CListCtrl*listMain,intcolSum);//初始化列表 CStringGetAppPath();//得到应用程序所在文献夹 BOOLFillList(CListCtrl*listMain);//填充列表 CStringGetFieldsName(intindex);//返回字段名字 intGetFeildsCount();//返回字段数量 //返回数据集数 longGetRecordCount(); voidWriteLog(CStringstrSql);//写日记文献 voidWriteLog1(CStringuserName);//写日记文献,谁谁登录};1、数据库操作函数对惯用数据库操作定义了有关函数。(1)连接数据库在类构造函数CADOConn中,声明数据库名称。CADOConn::CADOConn(){ m_DataType=1;//数据库类型Acess m_strData=_bstr_t("ShopData.mdb");//数据库名称}在OnInitCADOConn函数中,实现连接数据库。voidCADOConn::OnInitCADOConn(){ //初始化OLE/COM库环境 ::CoInitialize(NULL); try { //初始化指针 m_pConnection=NULL; //初始化指针 m_pRecordset=NULL; //创立Connection对象 m_pConnection.CreateInstance("ADODB.Connection"); //设立连接字符串,必要是BSTR型或者_bstr_t类型 _bstr_tstrConnect; switch(m_DataType) { case1://ACCESS strConnect=_bstr_t("Provider=Microsoft.Jet.OLEDB.4.0;"); strConnect=strConnect+_bstr_t("DataSource="); strConnect=strConnect+_bstr_t(IPAddress)+_bstr_t("\\data\\"); strConnect=strConnect+m_strData; break; case2://EXCEL strConnect=_bstr_t("Provider=Microsoft.Jet.OLEDB.4.0;"); strConnect=strConnect+_bstr_t("DataSource="); strConnect=strConnect+_bstr_t(GetAppPath())+_bstr_t("\\"); strConnect=strConnect+m_strData; strConnect=strConnect+";ExtendedProperties=Excel8.0"; break; case3://SQLSERVER strConnect="Provider=SQLOLEDB;Server="+MainIP+";Database=ShopData;uid=admin;pwd=123456"; break; } m_pConnection->Open(strConnect,"","",adModeUnknown); } //捕获异常 catch(_com_errore) { //显示错误信息 AfxMessageBox(e.Description()); } ASSERT(m_pConnection!=NULL);}(2)对数据库进行查询GetRecordSet函数实现执行Select查询语句,返回查询成果集_RecordsetPtr&CADOConn::GetRecordSet(CStringstrSQL){ try { //连接数据库,如果Connection对象为空,则重新连接数据库 if(m_pConnection==NULL)OnInitCADOConn(); strSQL.TrimLeft(); strSQL.TrimRight(); //创立记录集对象 m_pRecordset.CreateInstance(__uuidof(Recordset)); //获得表中记录 m_pRecordset->Open(_bstr_t(strSQL),m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText); } //捕获异常 catch(_com_errore) { //显示错误信息 AfxMessageBox(e.Description()); } ASSERT(m_pRecordset!=NULL); //返回记录集 returnm_pRecordset;}CADOConn类Open函数实现与GetRecordSet函数基本类似,只是它不返回记录集,而是打开数据库表。(3)执行数据库操作语句ExecuteSQL函数实现执行SQL数据操作语句,如INSERT/UPDATE/DELETE语句等。BOOLCADOConn::ExecuteSQL(CStringstrSQL){ try { //与否已经连接数据库 if(m_pConnection==NULL)OnInitCADOConn(); strSQL.TrimLeft(); strSQL.TrimRight(); m_pConnection->Execute(_bstr_t(strSQL),NULL,adCmdText); WriteLog(strSQL); returnTRUE; } catch(_com_errore) { AfxMessageBox(e.Description()); returnFALSE; }}2、记录集操作函数为了便于对记录集进行操作,在CADOConn类中定义了惯用记录集操作函数。GetValueInt实现了从记录集中获取不同类型字段值函数,以获取整形字段值。intCADOConn::GetValueInt(intindex){ _variant_tvValue;//var型返回值 _variant_tvIndex;//索引 intiValue;//数值返回值 vIndex.vt=VT_I2; vIndex.iVal=index; vValue=m_pRecordset->Fields->GetItem(vIndex)->Value;//获取索引字段值 switch(vValue.vt) { caseVT_NULL://为空值 iValue=0;//赋值 break; caseVT_ERROR://错误 iValue=0;//赋值 break; caseVT_EMPTY://不存在 iValue=0;//赋值 break; default: iValue=vValue.iVal;//获取值 } returniValue;//返回整数值}3、列表控件操作函数在CADOConn类中定义了列表控件操作函数,实现将记录集数据添加到指定列表控件中。其中InitList函数实现初始化列表控件。BOOLCADOConn::InitList(CListCtrl*listMain,intcolSum){ longlMax=0; _variant_tvIndex;//var类型索引 vIndex.vt=VT_I2; inti; lMax=m_pRecordset->Fields->Count;//获取记录集字段数 //设立列表框控件风格 listMain->SetExtendedStyle(LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT); for(i=0;i<lMax;i++)//遍历各字段 { CStringstrTitle=""; vIndex.iVal=i;//字段索引 //获取字段名称 strTitle=(LPCTSTR)m_pRecordset->Fields->GetItem(vIndex)->GetName(); //在列表框中添加列 listMain->InsertColumn(i,strTitle,LVCFMT_CENTER,100,0); } intintWidth=0;//列表框列宽度 for(i=0;i<colSum;i++)//遍历列表框中添加列 { //依照字段标题自动设立列宽 listMain->SetColumnWidth(i,LVSCW_AUTOSIZE_USEHEADER); intWidth=intWidth+listMain->GetColumnWidth(i);//计算列宽总和 } RECTrectList; listMain->GetWindowRect(&rectList);//获取列表框窗口区域 if(intWidth<(rectList.right-rectList.left))//使列表项布满列表框窗口 { intWidth=(rectList.right-rectList.left-intWidth)/colSum; listMain->SetColumnWidth(i,listMain->GetColumnWidth(i)+intWidth); } returnTRUE;}FillList函数用于向列表框中添加记录BOOLCADOConn::FillList(CListCtrl*listMain,intColOpenEnd){ inti,iType,iRow=0,listWidth=0; _variant_tvIndex;//var类型索引 longlMax=0; lMax=m_pRecordset->Fields->Count;//记录集字段数目 vIndex.vt=VT_I2; listMain->DeleteAllItems();//删除列表控件各列值 if(!m_pRecordset->adoEOF)//遍历记录集 { MoveFirst();//首条记录 while(!m_pRecordset->adoEOF) { for(i=0;i<lMax;i++) { CStringstrValue=""; vIndex.iVal=i;//字段索引 //获取字段类型 iType=m_pRecordset->Fields->GetItem(vIndex)->GetType(); switch(iType) { caseado_Field_Str: caseado_Field_Text://文本 strValue=GetValueString(i,0);//获取文本值 break; caseado_Field_Long://长整型 strValue=GetValueLongStr(i,0);//获取长整值并转换为文本 break; caseado_Field_Int://Int型 strValue=GetValueIntStr(i,0);//获取INT值并转换为文本 break; caseado_Field_Float://Float型 strValue=GetValueFloatStr(i,0,2);//获取Float值并转换为文本 break; caseado_Field_Double://Double型 strValue=GetValueDoubleStr(i,0,2);//获取Double值并转换为文本 break; caseado_Field_Byte://Byte型 strValue=GetValueByteStr(i,0);//获取Byte值并转换为文本 break; caseado_Field_Date://日期时间型 strValue=GetValueString(i,0);//获取日期时间值并转换为文本 break; default: strValue=""; break; } if(m_DataType==2)//Excel文献 strValue=GetValueString(i,0); if(i==0)//第一列 listMain->InsertItem(iRow,strValue,0);//添加行 else listMain->SetItemText(iRow,i,strValue);//设立行值 } m_pRecordset->MoveNext();//下一记录 iRow=iRow+1; } MoveFirst();//移向记录集开头 } if(listMain->GetItemCount()>0)//列表框具有列 { if(ColOpenEnd>0)//要展开列 { for(inti=0;i<ColOpenEnd;i++) { listMain->SetColumnWidth(i,LVSCW_AUTOSIZE);//自动设立列宽 listWidth=listMain->GetColumnWidth(i);//获取列宽 listMain->SetColumnWidth(i,LVSCW_AUTOSIZE_USEHEADER);//依照列标题设立列宽 if(listWidth<listMain->GetColumnWidth(i))//依照列标题设立列宽若不大于自动设立列宽 listMain->SetColumnWidth(i,LVSCW_AUTOSIZE_USEHEADER); } } else { listMain->SetColumnWidth(i,LVSCW_AUTOSIZE_USEHEADER);//依照列标题设立列宽 } } else//表中没有列 { for(i=0;i<lMax;i++) { listMain->SetColumnWidth(i,LVSCW_AUTOSIZE_USEHEADER); listWidth=listWidth+listMain->GetColumnWidth(i); } RECTrectList; listMain->GetWindowRect(&rectList); if(listWidth<(rectList.right-rectList.left)) { listWidth=(rectList.right-rectList.left-listWidth)/11; listMain->SetColumnWidth(i,listMain->GetColumnWidth(i)+listWidth); } } returnTRUE;}5.1.4数据库表操作类CtablePartInfo由于本项目模仿分布式数据库,对数据库某些表进行了分片、分派等冗余设计。因而,对数据库增、删、改、查要制定一定规则,来保证数据一致性,而这种规则不由于表不同而不同。为此,咱们设计了CtablePartInfo来统一执行这种规则。classtablePartInfo:publicCWnd{public: tablePartInfo(); tablePartInfo(CString_tableName); ~tablePartInfo();public: //依照表名tableName获得表分片和分派信息 voidGetTablePartInfo(); boolOperationOpen(CStringstrSQL,intnColumn); //依照表分片和分派信息,按增长规则执行数据库插入操作 boolOperationAdd(CStringstrSQL); //依照表分片和分派信息,按增长规则执行数据库修改操作 boolOperationModify(CStringstrSQL); //依照表分片和分派信息,按增长规则执行数据库查询操作 boolOperationSelect(CStringstrSQL); boolOperationSelect(CStringstrSQL,intnColumn); boolOperationSelectInital(CStringstrSQL,intnColumn); boolOperationSelectInital(CStringstrSQL); //依照表分片和分派信息,按增长规则执行数据库删除操作 boolOperationDelete(CStringstrSQL); //解决总站或者区域站点故障 voidHandleError(boolsuccess,intarea);public: intpart; intcopy; CListCtrl*m_list; CStringtableName; CStringstrIP; boolIsDone1; boolIsDone2; CStringErrorMessage;};下面以boolOperationAdd(CStringstrSQL)为例简介了为维护数据库一致性,对数据库更新规则详细实现。booltablePartInfo::OperationAdd(CStringstrSQL){ boolsuccess=true;//用于判断SQL语句与否执行成功 //一方面更新总站数据库中相应记录,由于所有信息都会在总公司中存在 CADOConnadoMain(3); success=adoMain.ExecuteSQL(strSQL,0); HandleError(success,0);//解决执行成果,执行故障则给出报错信息 if(success)//总站执行成功,接着进行区域站点操作 { if(0==m_globalAreaInt)//主站顾客添加数据 { if(1==copy)//冗余分派信息,同步各个区域站点数据 { CADOConnadoIP(3); CStringsqlstr="select*fromIPInfowherearea!=0"; adoIP.Open(sqlstr); //这里只有海淀和朝阳两个站点,因此预先申请两个CADIConn对象 CADOConnadoAcess1; CADOConnadoAcess2; inti=0; //循环更新每个区域站点 while(!adoIP.adoEOF()) { i++; strIP=IPAddress; IPAddress="\\\\"+adoIP.GetValueString(1,0); if(1==i)//解决海淀区数据库 { success=adoAcess1.ExecuteSQL(strSQL,1); HandleError(success,1); if(!success)//区域站点没有添加成功,这时总站撤销事务 { adoMain.m_pConnection->RollbackTrans(); adoMain.WriteLog(ErrorMessage,0); } //区域站点添加成功,需等待区域添加成功再提交事务 } if(2==i&&success)//区域站点添加成功,解决朝阳区 { success=adoAcess2.ExecuteSQL(strSQL,2); HandleError(success,2); if(!success)//区域站点没有添加成功 { adoMain.m_pConnection->RollbackTrans();//总站撤销事务 adoMain.WriteLog(ErrorMessage,0); adoAcess1.m_pConnection->RollbackTrans();//区域撤销事务 adoAcess1.WriteLog(ErrorMessage,1); } else//区域站点添加成功 { //总站和区域站点同步提交事务 adoAcess1.m_pConnection->CommitTrans(); adoAcess2.m_pConnection->CommitTrans(); adoMain.m_pConnection->CommitTrans(); } } adoIP.MoveNext(); IPAddress=strIP; } adoIP.ExitConnect(); adoAcess1.ExitConnect();//区域站点关闭数据库连接 adoAcess2.ExitConnect(); } else//数据没有copy则不用更新区域站点数据,总站提交事务 { adoMain.m_pConnection->CommitTrans(); } } else//分站顾客添加数据 { if(1==part)//数据表分片,向本地添加数据 { CADOConnadoAcess; success=adoAcess.ExecuteSQL(strSQL); HandleError(success,m_globalAreaInt); if(!success)//区域站点没有添加成功 {//总站撤销事务,写下撤销事务日记 adoMain.m_pConnection->RollbackTrans(); adoMain.WriteLog(ErrorMessage,0); } else//区域站点添加成功 { //总站和区域站点同步提交事务 adoAcess.m_pConnection->CommitTrans(); adoMain.m_pConnection->CommitTrans(); } adoAcess.ExitConnect();//区域站点关闭数据库连接 } else//数据表没有分片,则提交总站事务 { adoMain.m_pConnection->CommitTrans(); } } } adoMain.ExitConnect();//总站关闭数据库连接 returnsuccess;}5.2界面窗口设计系统主框架是使用MFC创立向导创立基于对话框应用程序,工程名为“ShopManage”。5.2.1系统启动登录开发系统启动时,一方面弹出登录对话框,顾客登录后,依照顾客权限显示主界面窗口或是销售开单窗口。系统启动时,一方面运营是CShopManageApp类InitInstance函数,在这里创立登陆对话框,登陆后依照顾客权限弹出相应对话框窗口。InitInstance函数实当代码如下。BOOLCShopManageApp::InitInstance(){ MainIP="3"; IPAddress=MainIP; IPAddressOrigin=MainIP; AfxEnableControlContainer(); CDlgLogodlgLog;//登录对话框 CShopManageDlgdlg;//主对话框 CDlgXiaoShouKanDandlgXiao;//销售开单对话框 inti; CStringstrSql; if(dlgLog.DoModal()!=IDOK)//登录失败 ::exit(0);//退出程序 CADOConnadoMain(3); strSql="select*fromAdminInfowherecode='"; strSql=strSql+dlgLog.strNo+"'"; adoMain.Open(strSql);//执行查询语句 if(!adoMain.adoEOF())//成果集不为空 { if(adoMain.MoveFirst()) { i=adoMain.GetValueInt(2); if(i==2)//销售员 { m_pMainWnd=&dlgXiao; dlgXiao.DoModal();//销售开单对话框 } else//管理员 { dlg.strNo=dlgLog.strNo;//管理员ID dlg.strName=dlgLog.strName;//管理员姓名 m_pMainWnd=&dlg; dlg.DoModal();//主对话框 } } } returnFALSE;}登录顾客验证操作在登录对话框类CDlgLogo“拟定”按钮响应函数OnOK中实现。voidCDlgLogo::OnOK(){ //TODO:Addextravalidationhere UpdateData(TRUE); CStringstrSql; CADOConnadoMain(3);//数据连接对象,顾客信息表只有总站上有,因此连接SQL数据库 strSql="select*fromAdminInfowherecode='"; strSql=strSql+m_str1+"'andpwd='"; strSql=strSql+m_str2+"'"; adoMain.OpenLogo(strSql);//执行查询 if(!adoMain.adoEOF())//成果不为空 { strName=adoMain.GetValueString(1,0);//顾客姓名 strNo=m_str1;//顾客ID m_globalArea=adoMain.GetValueString(7,0);//顾客区域 m_globalAreaInt=adoMain.GetValueInt(7); CDialog::OnOK();//关闭对话框 //依照顾客区域标志获得区域站点ip地址 CADOConnadoIP(3); CStringsqlstr="select*fromIPInfowherearea="+m_globalArea; adoIP.OpenLogo(sqlstr);//执行查询 if(!adoIP.adoEOF())//成果不为空 { IPAddress="\\\\"+adoIP.GetValueString(1,0); IPAddressOrigin="\\\\"+adoIP.GetValueString(1,0); } //写登录日记信息 adoMain.WriteLog1(m_str1); adoMain.WriteLog(strSql); adoIP.WriteLog(sqlstr); adoIP.ExitConnect(); } else MessageBox("密码或顾客ID错误!","提示",MB_OK|MB_ICONWARNING); adoMain.ExitConnect();}5.2.2主界面对话框设计系统创立是基于对话框应用程序,因而系统主界面是一种对话框窗口。系统中为对话框窗口添加了菜单项,为了以便进行惯用操作,在对话框中还添加了某些位图按钮。为对话框添加菜单栏,一方面需要在工程资源管理器重添加设计菜单项,然后在对话框属性对话框中,在Menu下拉列表框中,选取设计菜单资源ID即可。按钮控件则直接添加到主对话框模板中,需要设立Flat属性。在CShopManageDlg类头文献中,声明CMyMenu对象,并将按钮控件类型设立为CMyButton,代码如下。classCShopManageDlg:publicCDialog{//Constructionpublic: CShopManageDlg(CWnd*pParent=NULL); //standardconstructor CMyMenum_menu; CStringstrNo,strName; CMyButton m_ctrWarning; CMyButton m_ctrStore;……};在CShopManageDlg类初始化函数OnInitDialog中,初始化菜单和位图按钮设立,这里菜单和按钮设立分别采用自定义扩展类CMyMenu和CMyButton,它们对基本菜单和按钮控件外观作了定制,从而美化了程序界面。5.2.3通用报表对话框设计开发系统可以生成各种记录报表,在系统开发中,设计了一种通用报表对话框,这样就简化了程序开发。在通用报表对话框资源模板中,添加了一种列表控件用于显示报表数据,一种静态文本控件用于显示报表标题,尚有两个按钮控件,即“导出”按钮和“打印”按钮,分别用于导出报表和打印报表。通用报表对话框相应对话框类为CDLgReport,在其初始化函数OnInitDialog中,设立报表标题和报表数据,代码如下。BOOLCDLgReport::OnInitDialog(){ CDialog::OnInitDialog(); m_area.SetCurSel(m_globalAreaInt); if(0==biaozhi||0!=m_globalAreaInt) m_area.EnableWindow(FALSE); CStringarea; area.Format("%d",m_area.GetCurSel()); tablePartInfoOperate(strTableName); m_Btn1.SetXIcon(IDI_ICONBUTTON);//导出按钮 m_Btn2.SetXIcon(IDI_ICONBUTTON);//打印按钮 GetDlgItem(IDC_STATIC1)->SetFont(&ftHeader);//设立标题文本字体 GetDlgItem(IDC_STATIC1)->SetWindowText(strTitle);//设立标题 Operate.m_list=&m_listMain; CStringstr=strSQL+"area="+area; if(0==biaozhi) { str=strSql; } Operate.OperationSelectInital(str); returnTRUE;}在“打印”按钮响应函数中,实现弹出打印对话框,代码如下。voidCDLgReport::OnButton2()//打印{ //TODO:Addyourcontrolnotificationhandlercodehere CDlgPrintdlg;//打印对话框 dlg.strTitle=strTitle;//对话框标题 dlg.strSql=strSql;//查询语句 dlg.m_ListMain=&m_listMain;//列表控件 dlg.DoModal();}“导出”按钮可实现将报表数据导出到Excel文献中,按钮响应函数实当代码如下。函数重要通过自定义Excel对象操作类CMyExcel来实现导出数据到Excel文献中。voidCDLgReport::OnButton1(){ //TODO:Addyourcontrolnotificationhandlercodehere inti=0,j=0; CMyExcelexcel1;//Excel操作对象 CMyTimetime1;//时间操作对象 //打开文献对话框 CFileDialogdlg(FALSE,"xls","C:\\*.xls",OFN_NOCHANGEDIR,"EXCEL文献|*.xls"); CADOConnadoMain;//数据操作对象 time1.SetNow();//获取当前时间 if(dlg.DoModal()==IDOK) { excel1.Open();//打开Excel文献 excel1.AddSheet("导出");//添加Sheet页 excel1.AutoRange(); excel1.SetItemText(1,1,strTitle);//添加标题 adoMain.Open(strSql);//执行查询 //遍历列表框列 for(i=0;i<m_listMain.GetHeaderCtrl()->GetItemCount();i++) { //将列标题添加到Excel表单中 excel1.SetItemText(2,i+1,adoMain.GetFieldsName(i)); } adoMain.ExitConnect();//断开连接 for(i=0;i<m_listMain.GetItemCount();i++)//遍历记录集 { //依次将记录集各列添加到Excel表单中 for(j=0;j<m_listMain.GetHeaderCtrl()->GetItemCount();j++) { excel1.SetItemText(i+3,j+1,m_listMain.GetItemText(i,j)); } } excel1.SetItemText(i+3,1,time1.GetAllString(TRUE));//在Excel中添加时间 excel1.AutoColFit();//自动设立Excel列 excel1.SaveAs(dlg.GetPathName());//保存Excel文献 } excel1.Exit();//退出Excel对象}5.2.4打印对话框设计开发系统对所有记录报表都提供了打印功能。在报表对话框中,单击“打印”按钮,就会弹出相应打印对话框,在对话框中,通过使用CGridCtrl控件显示报表数据,且可在控件中编辑数据。系统设计了一种通过打印对话框,在其对话框资源模板中添加了3个按钮控件和一种顾客自定义控件,该自定义控件用于实现CGridCtrl控件,其相应对话框类为CDlgPrint。使用CGridCtrl控件可以实现类似EXCEL界面,可以在网上获取MFCGridcontrol控件代码文献,并将这些文献添加到工程中。在CDlgPrint类头文献中,新创立一种CGridCtrl对象,代码如下。classCDlgPrint:publicCDialog{//Constructionpublic: CDlgPrint(CWnd*pParent=NULL);//standardconstructor CStringstrSql; CStringstrTitle; CListCtrl*m_ListMain; CGridCtrlm_Grid;……};在DoDataExchange函数中为顾客自定义控件关联该对象,代码如下。voidCDlgPrint::DoDataExchange(CDataExchange*pDX){ CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDlgPrint) DDX_Control(pDX,IDC_GRID,m_Grid); //}}AFX_DATA_MAP}在对话框初始化函数OnInitDialog中,设立CGridCtrl控件属性,并将报表数据添加到CGridCtrl控件中,代码如下。BOOLCDlgPrint::OnInitDialog(){ CDialog::OnInitDialog(); CADOConnadoMain;//数据操作对象 inti,j; SetWindowText(strTitle);//设立对话框标题 adoMain.Open(strSql); m_Grid.SetRowCount(m_ListMain->GetItemCount()+1);//设立控件行 m_Grid.SetColumnCount(adoMain.GetFeildsCount());//设立控件列 m_Grid.SetEditable(TRUE);//控件可编辑m_Grid.SetTextBkColor(RGB(0xFF,0xFF,0xE0));//设立背景色 m_Grid.SetFixedColumnCount(1);//设立表固定列数 m_Grid.SetFixedRowCount(1);//设立表固定行数 for(i=0;i<adoMain.GetFe

温馨提示

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

最新文档

评论

0/150

提交评论