學(xué)院倉庫管理系統(tǒng)設(shè)計(jì)_第1頁
學(xué)院倉庫管理系統(tǒng)設(shè)計(jì)_第2頁
學(xué)院倉庫管理系統(tǒng)設(shè)計(jì)_第3頁
學(xué)院倉庫管理系統(tǒng)設(shè)計(jì)_第4頁
學(xué)院倉庫管理系統(tǒng)設(shè)計(jì)_第5頁
已閱讀5頁,還剩85頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、 HYPERLINK / 數(shù)據(jù)庫課程設(shè)計(jì)報(bào)告題目:倉庫治理系統(tǒng)組長:王 寧(P071513228)組員:胡樂樂(P071513227)徐 建(P071513237) 葛 東(P071513256) 張 超(P071513267)指導(dǎo)教師:曹永春計(jì)算機(jī)科學(xué)與信息工程學(xué)院倉庫治理系統(tǒng)一、設(shè)計(jì)目標(biāo)企業(yè)的倉庫物資治理往往復(fù)雜、繁瑣。本系統(tǒng)要緊針對企業(yè)生產(chǎn)所需要的各種設(shè)備而設(shè)計(jì),實(shí)施驗(yàn)收入庫并填寫入庫單和入庫登記;企業(yè)各個(gè)部門依照所需要提出物質(zhì)申請,打算員依照整個(gè)企業(yè)的需求開出物資設(shè)備出庫單,倉庫治理員依照出庫單核對發(fā)放設(shè)備;設(shè)備使用完畢需要及時(shí)歸還入庫,填寫還入庫單。系統(tǒng)還依照需要按照月、季、年進(jìn)行統(tǒng)

2、計(jì)分析,產(chǎn)生相應(yīng)報(bào)表。依照系統(tǒng)功能的要求,倉庫治理系統(tǒng)能夠分為日志治理、入庫、出庫、還庫、查詢、報(bào)表等要緊模塊。企業(yè)的物資供應(yīng)治理往往是專門復(fù)雜、繁瑣的。由于掌握的物資種類眾多,訂貨、治理、發(fā)放的渠道各有差異,各個(gè)企業(yè)之間的治理機(jī)制不盡相同,各類統(tǒng)計(jì)打算報(bào)表繁多,因此物資治理必須實(shí)現(xiàn)計(jì)算機(jī)化,而且必須依照企業(yè)的具體情況制定相應(yīng)的方案以便提高工作效率。依照當(dāng)前的企業(yè)治理體制,一般物資供應(yīng)治理系統(tǒng),總是依照所掌握的物資類不,相應(yīng)分成幾個(gè)科室來進(jìn)行物資的打算、訂貨、核銷托收、驗(yàn)收入庫。依照企業(yè)各個(gè)部門的來發(fā)送物資設(shè)備,并隨時(shí)按期進(jìn)行庫存盤點(diǎn)、做臺帳、依照企業(yè)自身領(lǐng)導(dǎo)和自身治理的需要按月、季、年進(jìn)行統(tǒng)

3、計(jì)分析,產(chǎn)生相應(yīng)的報(bào)表。為了加強(qiáng)相應(yīng)物資、設(shè)備的治理,要定期掌握其儲(chǔ)備、消耗情況,依照打算定額和實(shí)際消耗定額的比較,進(jìn)行定額治理。倉庫治理的物資在本章中要緊是企業(yè)生產(chǎn)所需的各種設(shè)備。進(jìn)貨時(shí)檢查合同確認(rèn)為有效托收之后,進(jìn)行驗(yàn)收入庫、填寫入庫單和入庫登記。企業(yè)各個(gè)部門依照所需要的物資設(shè)備總額和部門生產(chǎn)活動(dòng)所需要提出物資需求申請,打算員依照企業(yè)的需求開出物資設(shè)備出庫單,倉庫治理員依照出庫單核對發(fā)放設(shè)備。設(shè)備使用完畢需要及時(shí)歸還入庫,填寫還入庫單。系統(tǒng)還依照需要按照月、季、年進(jìn)行統(tǒng)計(jì)分析,產(chǎn)生相應(yīng)報(bào)表。為了跟好的理解該系統(tǒng)和讀明白該系統(tǒng)的源代碼,讀者應(yīng)對以下的知識點(diǎn)有所了解:Access數(shù)據(jù)庫操作的基

4、礎(chǔ)知識。ODBC數(shù)據(jù)源基礎(chǔ)知識。差不多的SQL語句,如添加、查詢、修改和刪除記錄語句。Visual C+界面設(shè)計(jì)和關(guān)于數(shù)據(jù)庫的基礎(chǔ)知識。二、系統(tǒng)設(shè)計(jì)倉庫治理的特點(diǎn)是信息處理量比較大,所治理的物資設(shè)備種類繁多,而且入庫單、出庫單、需求單等單據(jù)的發(fā)生量特不大,關(guān)聯(lián)信息多,查詢和統(tǒng)計(jì)的方式各不相同,在治理上實(shí)現(xiàn)起來有一定的困難。在治理的過程中經(jīng)常出現(xiàn)信息的重復(fù)傳遞;單據(jù)、報(bào)表的種類繁多,各個(gè)部門治理規(guī)格不統(tǒng)一等問題。在本系統(tǒng)的設(shè)計(jì)過程中,為了克服這些困難,滿足計(jì)算機(jī)治理的需要,采取了下面的一些原則:統(tǒng)一各種原始單據(jù)的格式,統(tǒng)一賬目和報(bào)表的格式。刪除不必要的治理冗余,實(shí)現(xiàn)治理規(guī)范化、科學(xué)化。程序代碼標(biāo)

5、準(zhǔn)化,軟件統(tǒng)一化,確保軟件的可維護(hù)性和有用性。界面盡量簡單化,做到有用、方便,盡量滿足企業(yè)中不同層次職員的需要。建立操作日志,系統(tǒng)自動(dòng)記錄所進(jìn)行的各種操作。1、系統(tǒng)功能分析 本例中的倉庫治理系統(tǒng)需要完成的功能要緊有以下幾點(diǎn): 倉庫治理各種信息的輸入,包括入庫、出庫、還庫、需求信息的輸入等。 倉庫治理各種信息的查詢、修改和維護(hù)。 設(shè)備采購報(bào)表的生成。 在庫存治理中加入最高儲(chǔ)備和最低儲(chǔ)備字段,對倉庫中的物資設(shè)備實(shí)現(xiàn)監(jiān)控和報(bào)警。 企業(yè)各部門的物資需求的治理。 操作日志的治理。 倉庫治理系統(tǒng)的使用關(guān)心。2、系統(tǒng)功能模塊設(shè)計(jì) 在系統(tǒng)功能分析的基礎(chǔ)上,結(jié)合Visual C+程序編制的特點(diǎn),得到如圖1所示的

6、系統(tǒng)功能模塊圖。倉庫治理系統(tǒng)倉庫治理系統(tǒng)系統(tǒng)模塊輸入模塊維護(hù)模塊查看模塊報(bào)表模塊關(guān)心模塊日志治理需求模塊還庫模塊出庫模塊入庫模塊圖1 系統(tǒng)功能模塊圖 系統(tǒng)要緊界面及流程如下所示。 程序開始運(yùn)行之后先出現(xiàn)如圖2的登陸界面。成功輸入用戶名和密碼后將進(jìn)入主對話框。圖2 登陸界面單擊“設(shè)備代碼”按鈕進(jìn)入設(shè)備代碼表(device_code)的治理。單擊“庫存信息”按鈕進(jìn)入現(xiàn)有庫存表(device)的治理。單擊“設(shè)備入庫”按鈕開始設(shè)備入庫操作,若成功,則在設(shè)備入庫表(device_in)中增加一條記錄,同時(shí)修改現(xiàn)有的庫存表(device)中的相關(guān)數(shù)據(jù)。單擊“設(shè)備出庫”按鈕開始設(shè)備出庫操作,如圖3所示。若成

7、功,則在設(shè)備出庫表(device)中的相關(guān)數(shù)據(jù)。 圖3 設(shè)備出庫登記窗口單擊下方的“出庫信息”按鈕進(jìn)入設(shè)備出庫表(device_out)的治理。如圖4所示。圖4 出庫信息治理界面單擊“設(shè)備還庫”按鈕開始設(shè)備還庫操作。若成功,則在設(shè)備還庫表(device_return)中增加一條記錄,同時(shí)修改現(xiàn)有庫存表(device)中的相關(guān)數(shù)據(jù)。單擊下方的“還庫信息”按鈕進(jìn)入設(shè)備還庫表(device_return)的治理。單擊“設(shè)備需求”進(jìn)入設(shè)備需求登記的界面,如圖5所示。用戶在那個(gè)地點(diǎn)填寫設(shè)備需求。若成功,則在設(shè)備需求表(device_need)中增加一條設(shè)備需求記錄。圖5 設(shè)備需求登記窗口單擊下方“需求信

8、息”按鈕進(jìn)入設(shè)備需求表(device_need)的治理。如圖6所示。單擊“操作日志”按鈕查看目前的所有操作日志記錄,在里面還能夠刪除所有日志記錄。單擊“關(guān)心”按鈕進(jìn)入聯(lián)機(jī)關(guān)心。單擊“關(guān)于”按鈕查看程序信息圖6 需求信息治理窗口三、數(shù)據(jù)庫設(shè)計(jì)1、數(shù)據(jù)庫需求分析在認(rèn)真調(diào)查企倉庫物資設(shè)備治理過程的基礎(chǔ)上,得到本系統(tǒng)所處理的數(shù)據(jù)流程,如圖7所示。 設(shè)備入庫設(shè)備入庫設(shè)備采購設(shè)備還庫設(shè)備出庫倉庫現(xiàn)有庫存各部門需求企業(yè)生產(chǎn)打算匯總圖 7 數(shù)據(jù)流程圖針對本實(shí)例,通過對企業(yè)倉庫治理的內(nèi)容和數(shù)據(jù)流程的分析,設(shè)計(jì)的數(shù)據(jù)項(xiàng)和數(shù)據(jù)結(jié)構(gòu)如下:設(shè)備代碼信息:其數(shù)據(jù)項(xiàng)有設(shè)備號、設(shè)備名稱現(xiàn)有庫存信息:其數(shù)據(jù)項(xiàng)有現(xiàn)有設(shè)備、現(xiàn)有數(shù)

9、目、總數(shù)目、最大庫存和最小庫存等設(shè)備使用信息:其數(shù)據(jù)項(xiàng)有使用的設(shè)備、使用部門、數(shù)目、使用時(shí)刻和出庫時(shí)狀態(tài)等設(shè)備采購信息:其數(shù)據(jù)項(xiàng)有采購的設(shè)備、采購員、供應(yīng)商、采購數(shù)目和采購時(shí)刻等設(shè)備歸還信息:其數(shù)據(jù)項(xiàng)歸還設(shè)備、歸還部門、歸還數(shù)目、歸還時(shí)刻和經(jīng)手人等設(shè)備需求信息:其數(shù)據(jù)項(xiàng)有需求的部門、需求設(shè)備、需求數(shù)目和需求時(shí)刻等2、數(shù)據(jù)概念結(jié)構(gòu)設(shè)計(jì)這一設(shè)計(jì)時(shí)期是在需求分析的基礎(chǔ)上,設(shè)計(jì)出能滿足用戶需求的各種實(shí)體,以及它們之間的關(guān)系,為后面的邏輯結(jié)構(gòu)設(shè)計(jì)打下基礎(chǔ)。本實(shí)例依照上面得設(shè)計(jì)規(guī)劃出實(shí)體有庫存實(shí)體,入庫實(shí)體、出庫實(shí)體、采購實(shí)體、還庫實(shí)體和需求實(shí)體。各實(shí)體的E-R圖及其關(guān)系描述如下:現(xiàn)有庫存現(xiàn)有庫存現(xiàn)有庫存

10、現(xiàn)有庫存現(xiàn)有庫存現(xiàn)有庫存現(xiàn)有庫存現(xiàn)有庫存設(shè)備號入庫入庫供應(yīng)商信息采購價(jià)格數(shù)量采購員設(shè)備號圖9 入庫實(shí)體E-R圖出庫出庫使用部門數(shù)量、時(shí)刻經(jīng)手人設(shè)備號圖10 出庫實(shí)體E-R圖部門需求部門需求需求部門需求數(shù)量需求時(shí)刻設(shè)備號 圖11 部門需求實(shí)體E-R圖設(shè)備還庫設(shè)備還庫還庫時(shí)刻人還庫數(shù)量經(jīng)手人設(shè)備號圖12 還庫實(shí)體E-R圖打算采購打算采購庫存信息供應(yīng)信息時(shí)刻設(shè)備號 圖13 打算采購實(shí)體E-R圖入庫入庫 現(xiàn)有庫存 出庫 還庫 部門需求設(shè)備采購圖 14 實(shí)體和實(shí)體之間的關(guān)系E-R圖3、數(shù)據(jù)庫邏輯結(jié)構(gòu)設(shè)計(jì)在上面的實(shí)體以及實(shí)體之間的關(guān)系的基礎(chǔ)上,形成數(shù)據(jù)庫中的表格和各個(gè)表格之間的關(guān)系。倉庫治理系統(tǒng)數(shù)據(jù)庫中的

11、各個(gè)表格的設(shè)計(jì)結(jié)果如下面的幾個(gè)表格所示。每個(gè)表格表示在數(shù)據(jù)庫中的一個(gè)表。 列名 數(shù)據(jù)類型 可否為空 講明 CodeVARCHAR2(6) NOTNULL 設(shè)備號(主鍵) NameVARVHAR2(20) NULL 設(shè)備名稱設(shè)備代碼表device_code 列名 數(shù)據(jù)類型 可否為空 講明CodeVARCHAR2(6)NOTNULL設(shè)備號In_dateDATENOTNULL入庫時(shí)刻(主鍵)ProviderVARCHAR2(20)NULL供應(yīng)商TelenoVARCHAR2(20)NULL供應(yīng)商電話In_numberNUMBER(6)NULL入庫數(shù)量PriceNUMBER(6)NULL價(jià)格BuyerV

12、ARCHAR2(10)NULL采購設(shè)備庫表device_in列名 數(shù)據(jù)類型 可否為空 講明CodeVARCHAR2(6)NOTNULL設(shè)備號DepartmentVARCHAR2(20)NULL使用部門Out_dateDATENULL出庫時(shí)刻(主鍵)Out_stateNUMBER(1)NULL出庫狀況Out_personVARCHAR2(10)NULL經(jīng)手人Out_numberNUMBER2(10)NOTNULL出庫數(shù)量TakerVARCHAR2(10)NULL領(lǐng)取UsageVARCHAR2(20)NULL用途設(shè)備出庫表device_out列名數(shù)據(jù)類型可否為空講明codeVARCHAR2(6)N

13、OT NULL設(shè)備號(主鍵)now_numberNUMBER(6)NULL現(xiàn)有庫存high_numberNUMBER(6)NULL最大庫存low_numberNUMBER(6)NULL最小庫存total_numberNUMBER(6)NULL總數(shù)現(xiàn)有數(shù)據(jù)庫表device列名數(shù)據(jù)類型可否為空講明codeVARCHAR2(6)NOT NULL設(shè)備號departmentVARCHAR2(20)NOT NULL部門名稱need_numberNUMBER(6)NULL需要數(shù)量begin_dateDATENULL需求開始時(shí)刻end_dateDATEMULL需求結(jié)束時(shí)刻 設(shè)備需求表 device_need列

14、名數(shù)據(jù)類型可否為空講明codeVARCHAR2(6)NOT NULL設(shè)備號return_dateDATENULL還庫時(shí)刻(主鍵)keeperVARCHAR2(10)NULL倉庫治理員return_numberNUMBER(6)NULL歸還數(shù)量return_personVARCHAR2(10)NULL歸還人 設(shè)備還庫表device_return列名數(shù)據(jù)類型可否為空講明do_userVARCHAR2(10)NOT NULL操作員do_whatVARCHAR2(40)NOT NULL操作內(nèi)容do_dateDATENOT NULL操作時(shí)刻操作日志表howdo列名數(shù)據(jù)類型可否為空講明codeVARCHA

15、R2(6)NOT NULL設(shè)備號now_numberNUMBER(6)NULL現(xiàn)有庫存total_numberNUMBER(6)NULL總庫存max_numberNUMBER(6)NULL購買數(shù)量providerVARCHAR(2)NULL供應(yīng)商priceNUMBER(6)NULL價(jià)格buy_dateDATENULL打算采購時(shí)刻(主鍵)設(shè)備采購打算表 device_wantbuy4、數(shù)據(jù)庫結(jié)構(gòu)的實(shí)現(xiàn) = 1 * GB3 創(chuàng)建設(shè)備代碼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 創(chuàng)建設(shè)備入庫表 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 創(chuàng)建設(shè)備出庫表 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 創(chuàng)建現(xiàn)有庫存表 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 創(chuàng)建部門需求表 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 創(chuàng)建設(shè)備還庫表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 創(chuàng)建設(shè)備采購打算表 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 創(chuàng)建操作日志表 howdoCREATE TABLE “DMS”,howdo(do_user VARCHAR2(10) NOT NULL,do_what VARCHAR2(40) NOT NULL,do_date DATE NOT NULL,)TABLESPACE “USER_DATA”;四、系統(tǒng)實(shí)現(xiàn)1、創(chuàng)建應(yīng)用程序此倉庫系統(tǒng)應(yīng)用程序的創(chuàng)建步驟如下: = 1 * GB2 、選擇菜單“File|New”中的“新建項(xiàng)目”選項(xiàng)卡中“MFC AppWizard(exe)”,設(shè)置合適的目錄和項(xiàng)目名,比如“E:Projects”目錄下的“DMS”項(xiàng)目。 = 2 * GB2 、創(chuàng)建一個(gè)對話框應(yīng)用程序(“

23、Dialog Based”),單擊“Next”按鈕。 = 3 * GB2 、由于在那個(gè)項(xiàng)目中將要使用ADO,因此在MFC AppWizard 的第2步,需要選中“Automation”選項(xiàng),使應(yīng)用程序能夠支持自動(dòng)化對象,如圖15所示。圖15 使應(yīng)用程序支持自動(dòng)化(Automation) = 4 * GB2 、單擊“Finish”按鈕,結(jié)束項(xiàng)目的創(chuàng)建。至此一個(gè)基于對話框的應(yīng)用程序框架就搭建好了。主對話框名為CDMSDlg。 = 5 * GB2 、項(xiàng)目創(chuàng)建完畢之后,在頭文件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行,那個(gè)地點(diǎn)定義了一個(gè)inline函數(shù)TESTHER,它的作用是測試COM函數(shù)的返回值,在那個(gè)返回值包含一個(gè)錯(cuò)誤的時(shí)候,拋出一個(gè)_co

25、m_error型的異常。ADO作為一個(gè)COM組件接口,它的許多函數(shù)都會(huì)返回一個(gè)HRESULT型的值作為結(jié)果。假如在每一步都用SUCCEEDED或FAILED宏測試返回值的話,將會(huì)不勝其煩,還有可能制造出一連串嵌套的if語句如此不美觀的代碼。那個(gè)函數(shù)簡化了這種驗(yàn)證操作,利用C+的異常處理機(jī)制,使代碼顯得緊湊而高效,為后面的工作帶來專門大方便。第4行定義了一個(gè)宏。這是不同的后臺數(shù)據(jù)庫對SQL語句中日期的用法要求不同引起的。比如Access數(shù)據(jù)庫要求SQL語句中的日期用兩個(gè)#字符括起,而其他的數(shù)據(jù)庫可能需要使用單引號或者雙引號。因此在那個(gè)地點(diǎn)定義了那個(gè)DATEFMT宏,為了方便程序在不同的后臺數(shù)據(jù)庫

26、鍵切換。這是一個(gè)在開發(fā)的時(shí)候需要注意的細(xì)節(jié),后面還會(huì)具體提到。2、COM知識預(yù)備下面介紹一些關(guān)于COM知識。這部分內(nèi)容是針對那些沒有學(xué)習(xí)過的COM技術(shù)的讀者,目的是為他們理解ADO提供一些背景知識。COM技術(shù)在微軟公司的應(yīng)用中能夠講是無處不在,Windows系統(tǒng)相當(dāng)多的服務(wù)都以這種方式提供,例如聞名的DirectX,還有在這一章中廣泛應(yīng)用的ADO。ADO的底層是OLE DB,他本身則是對OLE DB的一個(gè)COM包裝。因此具備一些COM的知識,對使用ADO是專門有關(guān)心的,但并不是講必須要精通COM才能使用ADO。事實(shí)上,在一般的應(yīng)用中,只需要理解下面這段代碼即可。/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下面的語句聲明了一個(gè)_bstr_t型的變量,_bstr_t是對BSTR類型的一個(gè)

30、封裝。_bstr_t strSQL(“SELETE *FROM DEVICE_WANTBUY”);關(guān)于BSTR,通俗地講,它是COM中使用的字符串,與一般C程序中的字符串的區(qū)不在于:它一個(gè)帶有字符計(jì)數(shù)值的字符串。它的字符計(jì)數(shù)值在字符數(shù)組的前面。它保存的在字符是所謂的“寬字符”(Wide character)。因此,關(guān)于一個(gè)BSTR而言,下面的語句確實(shí)是錯(cuò)的。BSTR str=L”Some words”;正確的做法是:Wchar_t st_=L”Some words”BSTR str;Bstr=SysAllocString(str_)釋放一個(gè)SBSTR指針時(shí),則調(diào)用SysFreeString函數(shù)

31、。每次都如此操控字符串未免太過苦惱,因此Visual C+ 里提供了_bstr_t那個(gè)類對BSTR做了封裝,使程序員能夠簡單的對這種COM 字符串進(jìn)行操作了。 = 2 * GB3 、IADORecordBinding和Iunkown一個(gè)COM組件包含了許多COM對象,程序員通過“接口”來操控這些對象,或者講,這些對象通過提供給程序員的接口來實(shí)現(xiàn)自己的功能。下面這行代碼中的IADORecordBind確實(shí)是一個(gè)指向這種接口的指針。IADORecordBingding *picRs=NULL; /Interface Pointer declared(VC+ Extension)每個(gè)接口差不多上從I

32、Unkown那個(gè)接口派生出來的。IUkown接口聲明了3個(gè)純虛函數(shù):HRESULT QueryInterface(REFID rilid,void*ppvObject);ULONG AddRef();ULONG AddRef();一般來講,不能直接擁有一個(gè)IADORecordBind或者IFoo、IBirdISomeInterface諸如此類的接口對象,程序員只能得到一個(gè)接口的指針,就像下面的這行代碼:pRst-QueryInterface(_uuidof(IADORecordBingding),(LPVOID*)&picRs);這行代碼解釋了IUknown接口中QueryInterfae方法

33、的最差不多的用法:程序員用它來得到COM對象支持的某個(gè)接口的指針。如上例中,pRst時(shí)某一個(gè)COM對象提供的一個(gè)接口指針,程序員從某本書上(比如MSDN)明白了那個(gè)對象一定擁有一個(gè)IADORecordBinding型的接口,因此調(diào)用上面那行代碼,得到了那個(gè)IADORecordBinding接口的指針。然后就能夠使用IADORecordBinding接口里聲明的那些方法了。如上所講,一個(gè)COM對象,程序員往往不能直接擁有它的實(shí)例,而只是它的接口的指針。那什么時(shí)候來釋放那個(gè)對象呢?這確實(shí)是AddRef和Release方法的用途。得到了一個(gè)接口指針,開始使用一個(gè)COM對象,就要調(diào)用它的AddRef方

34、法增加它內(nèi)部的一個(gè)引用計(jì)數(shù);使用完之后則調(diào)用Release方法減少那個(gè)計(jì)數(shù)。假如計(jì)數(shù)為零,則差不多講明沒有人使用,那個(gè)COM對象就會(huì)自己銷毀自己。原則上講,同一個(gè)對象提供的不同接口,AddRef和Release的效果差不多上一樣的。因此在使用完一個(gè)COM接口指針之后,一定要如此:picRs-Release();假如忽略了這一句,就會(huì)造成一個(gè)COM對象及他所掌握的資源不能被正確釋放。 = 3 * GB3 RecordsetPtr和智能指針如上一段所講,使用完一個(gè)接口之后不記得調(diào)用Release是一件和糟糕的事,為了彌補(bǔ)這一點(diǎn),就要寫出一大串嵌套的if語句,降低了程序的易讀性。程序就會(huì)拋出異常,而

35、程序員又沒有寫出捕獲這種異常的代碼(往往也不能寫,誰也無法預(yù)料自己調(diào)用的某個(gè)庫函數(shù)會(huì)跑出什么樣的異常),如此也會(huì)躍過某個(gè)原本不想躍過的Release。如何解決那個(gè)問題呢?一種方法是用try_finally語句,然而由于現(xiàn)有編譯器的缺陷,包含那個(gè)語句的代碼編譯出來的效率較低。這就用到了“智能指針那個(gè)工具。_RecordsetPtr pRs=NULL上面這行代碼聲明的變量確實(shí)是一個(gè)智能指針。從他的名字上看,他是對Recordset這種對象的指針進(jìn)行了包裝。TESTHr(pRst.CreateInstance(_uuidof(Recordset);這一句創(chuàng)建了一個(gè)Recordset型的COM對象,并

36、對智能指針賦值。在制作所在的函數(shù)體結(jié)束時(shí),智能指針對象從棧中析構(gòu),在它的析構(gòu)函數(shù)里調(diào)用了它所包含接口的Release方法。由它的工作原理看出,它解決了上面的問題棧中對象的析構(gòu)函數(shù)不管如何差不多上會(huì)被調(diào)用的,即使函數(shù)發(fā)生了異常而退出的情況也是如此。除此之外,智能指針能夠在接口指針賦值是自動(dòng)調(diào)用AddRef方法這也是一個(gè)容易犯得錯(cuò)誤。它通過重載運(yùn)算符,使得它在使用時(shí),和一般的接口指針毫無二致。3、操作日志模塊的設(shè)計(jì) = 1 * GB3 、寫日志模塊 通過操作日志模塊,該系統(tǒng)每一次改變數(shù)據(jù)庫數(shù)據(jù)的操作都會(huì)在操作日志表格中有相應(yīng)的記錄。如此能夠增強(qiáng)操作人員的責(zé)任感,提高系統(tǒng)的安全性,也利于維護(hù)數(shù)據(jù)庫數(shù)

37、據(jù)的完整性。此外,一個(gè)翔實(shí)的操作日志,也給開發(fā)過程中的調(diào)試、除錯(cuò)帶來專門大便利,因此那個(gè)模塊的設(shè)計(jì)被改在了最前面。先定義一個(gè)名為Clogmngr的類:/ LogMngr.h/定義一個(gè)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;在那個(gè)類中,保存了一個(gè)數(shù)據(jù)庫連接的指針m_DBCnt和當(dāng)前用戶的ID(m_user)。在主對話框CDMSDlg中加入了一個(gè)CLogMngr型的成員變量,并在CDMSDlg:OnInitDialog()中調(diào)用其Setup方法進(jìn)行初始化,設(shè)置好數(shù)據(jù)庫連接指針和用戶名。如此當(dāng)程序中某處需要寫信息進(jìn)行操作日志的時(shí)候,只需要調(diào)用那個(gè)類的AddLog方法即可。下面是CLogMngr:AddLog內(nèi)部實(shí)現(xiàn)的詳細(xì)過程。/LogMngr.cpp/向數(shù)據(jù)庫中添加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方法,直接執(zhí)行SQL語句,向表中加入了一條包含了操作者、操作時(shí)刻和操作內(nèi)容3個(gè)字段的記錄。直接使用了SQL語句的方法在表比較簡單的時(shí)候?qū)iT快捷,但在表包含比較多的字段的時(shí)候,就不太有用了。對日志表,我們暫且先用這種方法。 = 2 * GB3 、讀日志模塊在項(xiàng)目資源中加入一個(gè)對話框,它包含了一個(gè)列表框控件,幾個(gè)編輯框和兩個(gè)按鈕。那個(gè)窗體用以顯示系統(tǒng)所用的日志記錄。它還將實(shí)現(xiàn)清空所有記錄的功能(注意為了保證日

41、志記錄的完整性、安全性,不能單獨(dú)刪除某條記錄。)在刪除所有記錄時(shí),用SQL語句顯得專門方便。然而主意最好不要用那個(gè)“Delete * FROM HOWDO”如此的語句,而是使用下面的“TRUNCATETABLE”語句,它的速度比Delete快。/DlgViewLog.cpp/刪除所有日志記錄的函數(shù)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();此模塊的時(shí)刻和數(shù)據(jù)處理與后面的類似,那個(gè)地點(diǎn)暫不敘述。最后整個(gè)船體的外表如圖16所示。 圖16 查看日志窗口4、登錄窗口的設(shè)計(jì)在CDMSDlg:OnInitDialog()中加入如下一段代碼:/DMSDlg.cpp/彈出登錄界面CDlgLogIn dlg;doif (!dlg.DoModal()EndDialog(0); while (dlg.m_UsrName.GetLength()=0);它的目的是彈出圖17所示的登錄界面,并從中獵取一個(gè)有效的用戶名。圖17 登錄界面在得到有效的用戶名(字符串長度非0)后,程序

43、用如下的代碼嘗試連接數(shù)據(jù)庫,初始化成員變量(Connection指針和ClogMngr的實(shí)例)。在連接成功后,寫登錄記錄進(jìn)入操作日志。/ DMSDlg.cpp/建立數(shù)據(jù)庫連接,初始化成員變量/登錄庫,如失敗,則關(guān)閉程序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(登錄數(shù)據(jù)庫);catch(_com_error& e) AfxMessageBox(e.ErrorMessage();this-EndDialog(0); 最后不忘了在程序結(jié)束的時(shí)候關(guān)閉數(shù)據(jù)庫連接。/ DMSDlg.cpp/void CDMSDlg:OnDestroy() CDialog:OnDestroy(); m_DBCnt-Close();5、主對話框的設(shè)計(jì)登錄完成后,顯示出主對話框。它的界面如圖18所示,單擊某個(gè)按鈕就能彈出某個(gè)功能的界面。注意到按鈕的排布時(shí)按照所處的模塊分類的。 圖18 主對話框界面 以其中“設(shè)備代碼”按鈕為例,講明他的

45、事件處理函數(shù)。代碼如下: /DMSDlg.cpp /顯示設(shè)備代碼治理界面 void CDMSDlg:OnBtnDevcode() CDlgDevcode dlg;dlg.Setup(m_DBCnt,&m_logMngr);this-ShowWindow(SW_HIDE);dlg.DoModal();this-ShowWindow(SW_SHOW);從上面的代碼看出,當(dāng)單擊“設(shè)備代碼”按鈕時(shí),程序構(gòu)造一個(gè)CDlgDevcode型對話框?qū)嵗?,通過它的Setup函數(shù)賦給它一個(gè)數(shù)據(jù)庫連接指針和一個(gè)日志治理對象實(shí)例的指針,然后主對話框隱藏,直到子對話框事物處理結(jié)束。6、設(shè)備代碼治理窗口的建立設(shè)備代碼表格

46、(device_code)經(jīng)常被其他表格引用,如獵取合法編碼、由設(shè)備編碼號查找設(shè)備名稱等。因此自日志模塊和主對話框完成之后,先建立那個(gè)表格的治理模塊。對話框類名為CDlgDevcode,設(shè)計(jì)如圖19所示。圖19 設(shè)備代碼治理窗口那個(gè)地點(diǎn)用一個(gè)列表框控件顯示讀取的數(shù)據(jù)記錄。在CDlgDevcode:OnInitDialog()中對那個(gè)控件(m_list)進(jìn)行初始化(分割列、設(shè)置列寬、設(shè)置風(fēng)格等)。/DlgDevcode.cpp/對話框的初始化BOOL CDlgDevcode:OnInitDialog() CDialog:OnInitDialog();m_list.InsertColumn(0,設(shè)

47、備號);m_list.InsertColumn(1,設(shè)備名);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),定義了當(dāng)表格某整

48、行被選中時(shí),將此行的完整數(shù)據(jù)在表格控件的右側(cè)顯示出來。以后的各個(gè)模塊都用到了那個(gè)方法,這部分的代碼如下:/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,設(shè)備號);m_list.InsertColumn(1,設(shè)備名);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(添加設(shè)備記錄。); 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(刪除設(shè)備記錄。); 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(更新設(shè)備記錄。); RefreshData(); 由于那個(gè)表格比較簡單,讀者能夠看出,里面所有的數(shù)據(jù)操作差不多上由SQL語句直接完成的,對數(shù)據(jù)的操控則通過VARIANT型變量進(jìn)行,在此略微講解一下VARIANT類型。VARIANT類型是COM技術(shù)中專門重要的一種數(shù)據(jù)類型,經(jīng)常用于在組件之間傳遞類型不定的參數(shù)。它的定義如下: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 它實(shí)質(zhì)上是一個(gè)結(jié)構(gòu)體,第1個(gè)成員變量VT指明了VARIVAT當(dāng)前包含的類型;

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論