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

下載本文檔

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

文檔簡介

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

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

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

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

5、冗余,實現(xiàn)管理規(guī)范化、科學化。·程序代碼標準化,軟件統(tǒng)一化,確保軟件的可維護性和實用性。·界面盡量簡單化,做到實用、方便,盡量滿足企業(yè)中不同層次員工的需要。·建立操作日志,系統(tǒng)自動記錄所進行的各種操作。1、系統(tǒng)功能分析 本例中的倉庫管理系統(tǒng)需要完成的功能主要有以下幾點: ·倉庫管理各種信息的輸入,包括入庫、出庫、還庫、需求信息的輸入等。 ·倉庫管理各種信息的查詢、修改和維護。 ·設(shè)備采購報表的生成。 ·在庫存管理中加入最高儲備和最低儲備字段,對倉庫中的物資設(shè)備實現(xiàn)監(jiān)控和報警。 ·企業(yè)各部門的物資需求的管理。 

6、83;操作日志的管理。 ·倉庫管理系統(tǒng)的使用幫助。2、系統(tǒng)功能模塊設(shè)計 在系統(tǒng)功能分析的基礎(chǔ)上,結(jié)合Visual C+程序編制的特點,得到如圖1所示的系統(tǒng)功能模塊圖。倉庫管理系統(tǒng)系統(tǒng)模塊輸入模塊維護模塊查看模塊報表模塊幫助模塊日志管理需求模塊還庫模塊出庫模塊入庫模塊圖1 系統(tǒng)功能模塊圖 系統(tǒng)主要界面及流程如下所示。 程序開始運行之后先出現(xiàn)如圖2的登陸界面。成功輸入用戶名和密碼后將進入主對話框。圖2 登陸界面單擊“設(shè)備代碼”按鈕進入設(shè)備代碼表(device_code)的管理。單擊“庫存信息”按鈕進入現(xiàn)有庫存表(device)的管理。單擊“設(shè)備入庫”按鈕開始設(shè)備入庫操作,若成功,則在設(shè)備

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

8、圖5所示。用戶在這里填寫設(shè)備需求。若成功,則在設(shè)備需求表(device_need)中增加一條設(shè)備需求記錄。圖5 設(shè)備需求登記窗口單擊下方“需求信息”按鈕進入設(shè)備需求表(device_need)的管理。如圖6所示。單擊“操作日志”按鈕查看目前的所有操作日志記錄,在里面還可以刪除所有日志記錄。單擊“幫助”按鈕進入聯(lián)機幫助。單擊“關(guān)于”按鈕查看程序信息圖6 需求信息管理窗口三、數(shù)據(jù)庫設(shè)計1、數(shù)據(jù)庫需求分析在仔細調(diào)查企倉庫物資設(shè)備管理過程的基礎(chǔ)上,得到本系統(tǒng)所處理的數(shù)據(jù)流程,如圖7所示。 設(shè)備入庫設(shè)備采購設(shè)備還庫設(shè)備出庫倉庫現(xiàn)有庫存各部門需求企業(yè)生產(chǎn)計劃匯總圖 7 數(shù)據(jù)流程圖針對本實例,通過對企業(yè)倉庫

9、管理的內(nèi)容和數(shù)據(jù)流程的分析,設(shè)計的數(shù)據(jù)項和數(shù)據(jù)結(jié)構(gòu)如下:·設(shè)備代碼信息:其數(shù)據(jù)項有設(shè)備號、設(shè)備名稱·現(xiàn)有庫存信息:其數(shù)據(jù)項有現(xiàn)有設(shè)備、現(xiàn)有數(shù)目、總數(shù)目、最大庫存和最小庫存等·設(shè)備使用信息:其數(shù)據(jù)項有使用的設(shè)備、使用部門、數(shù)目、使用時間和出庫時狀態(tài)等·設(shè)備采購信息:其數(shù)據(jù)項有采購的設(shè)備、采購員、供應(yīng)商、采購數(shù)目和采購時間等·設(shè)備歸還信息:其數(shù)據(jù)項歸還設(shè)備、歸還部門、歸還數(shù)目、歸還時間和經(jīng)手人等·設(shè)備需求信息:其數(shù)據(jù)項有需求的部門、需求設(shè)備、需求數(shù)目和需求時間等2、數(shù)據(jù)概念結(jié)構(gòu)設(shè)計這一設(shè)計階段是在需求分析的基礎(chǔ)上,設(shè)計出能滿足用戶需求的各

10、種實體,以及它們之間的關(guān)系,為后面的邏輯結(jié)構(gòu)設(shè)計打下基礎(chǔ)。本實例根據(jù)上面得設(shè)計規(guī)劃出實體有庫存實體,入庫實體、出庫實體、采購實體、還庫實體和需求實體。各實體的E-R圖及其關(guān)系描述如下:現(xiàn)有庫存現(xiàn)有庫存現(xiàn)有庫存現(xiàn)有庫存設(shè)備號圖8 庫存實體E-R圖入庫供應(yīng)商信息采購價格數(shù)量采購員設(shè)備號圖9 入庫實體E-R圖出庫使用部門數(shù)量、時間經(jīng)手人設(shè)備號圖10 出庫實體E-R圖部門需求需求部門需求數(shù)量需求時間設(shè)備號 圖11 部門需求實體E-R圖設(shè)備還庫還庫時間人還庫數(shù)量經(jīng)手人設(shè)備號圖12 還庫實體E-R圖計劃采購庫存信息供應(yīng)信息時間設(shè)備號 圖13 計劃采購實體E-R圖入庫 現(xiàn)有庫存 出庫 還庫 部門需求設(shè)備采購

11、圖 14 實體和實體之間的關(guān)系E-R圖3、數(shù)據(jù)庫邏輯結(jié)構(gòu)設(shè)計在上面的實體以及實體之間的關(guān)系的基礎(chǔ)上,形成數(shù)據(jù)庫中的表格和各個表格之間的關(guān)系。倉庫管理系統(tǒng)數(shù)據(jù)庫中的各個表格的設(shè)計結(jié)果如下面的幾個表格所示。每個表格表示在數(shù)據(jù)庫中的一個表。 列名 數(shù)據(jù)類型 可否為空 說明 CodeVARCHAR2(6) NOTNULL 設(shè)備號(主鍵) NameVARVHAR2(20) NULL 設(shè)備名稱設(shè)備代碼表device_code 列名 數(shù)據(jù)類型 可否為空 說明CodeVARCHAR2(6)NOTNULL設(shè)備號In_dateDATENOTNULL入庫時間(主鍵)ProviderVARCHAR2(20)NULL供

12、應(yīng)商TelenoVARCHAR2(20)NULL供應(yīng)商電話In_numberNUMBER(6)NULL入庫數(shù)量PriceNUMBER(6)NULL價格BuyerVARCHAR2(10)NULL采購設(shè)備庫表device_in列名 數(shù)據(jù)類型 可否為空 說明CodeVARCHAR2(6)NOTNULL設(shè)備號DepartmentVARCHAR2(20)NULL使用部門Out_dateDATENULL出庫時間(主鍵)Out_stateNUMBER(1)NULL出庫狀況Out_personVARCHAR2(10)NULL經(jīng)手人Out_numberNUMBER2(10)NOTNULL出庫數(shù)量TakerVAR

13、CHAR2(10)NULL領(lǐng)取UsageVARCHAR2(20)NULL用途設(shè)備出庫表device_out列名數(shù)據(jù)類型可否為空說明codeVARCHAR2(6)NOT 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_numberN

14、UMBER(6)NULL需要數(shù)量begin_dateDATENULL需求開始時間end_dateDATEMULL需求結(jié)束時間 設(shè)備需求表 device_need列名數(shù)據(jù)類型可否為空說明codeVARCHAR2(6)NOT NULL設(shè)備號return_dateDATENULL還庫時間(主鍵)keeperVARCHAR2(10)NULL倉庫管理員return_numberNUMBER(6)NULL歸還數(shù)量return_personVARCHAR2(10)NULL歸還人 設(shè)備還庫表device_return列名數(shù)據(jù)類型可否為空說明do_userVARCHAR2(10)NOT NULL操作員do_wh

15、atVARCHAR2(40)NOT NULL操作內(nèi)容do_dateDATENOT NULL操作時間操作日志表howdo列名數(shù)據(jù)類型可否為空說明codeVARCHAR2(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價格buy_dateDATENULL計劃采購時間(主鍵)設(shè)備采購計劃表 device_wantbuy4、數(shù)據(jù)庫結(jié)構(gòu)的實現(xiàn)創(chuàng)建設(shè)備代碼device_codeC

16、REATE TABLE “DMS”.device_code(code VARCHAR2(6) NULL,name VARCHAR2(20) NULL,CONSTRANT code_code_pk PRIMARY KEY(code)TABLESPACE”USER_DATA”;創(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(

17、6) NULL,price NUMBER(6) NULL,buyer VARCHAR2(10) NULL,CONSTRAINT in_date_pk PRIMARY KEY(in_date)TABLESPACE “USER_DATA”;創(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_nu

18、mber NUMBER(6) NOT NULL,taker VARCHAR2(10) NULL,usage VARCHAR2(20) NULL,CONSTRAINT out_date_pk PRIMARY KEY(out_date)TABLESPACE”USER_DATA”;創(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(

19、6) NULL,CONSTRAINT device_code_pk PRIMARY KEY(code)TABLESPACE”USER_DATA”;創(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”;創(chuàng)建設(shè)備還庫表device_returnCREATE

20、 TABLE “DMS”,device_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”;創(chuàng)建設(shè)備采購計劃表 device_wantbuyCREATE TABLE

21、“DMS”,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”;創(chuàng)建操作

22、日志表 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)實現(xiàn)1、創(chuàng)建應(yīng)用程序此倉庫系統(tǒng)應(yīng)用程序的創(chuàng)建步驟如下:、選擇菜單“”中的“新建項目”選項卡中“MFC AppWizard(exe)”,設(shè)置合適的目錄和項目名,比如“E:Projects”目錄下的“DMS”項目。、創(chuàng)建一個對話框應(yīng)用程序(“Dialog Based”),單擊“Next”按鈕。、由于在這個項目中將要

23、使用ADO,所以在MFC AppWizard 的第2步,需要選中“Automation”選項,使應(yīng)用程序能夠支持自動化對象,如圖15所示。圖15 使應(yīng)用程序支持自動化(Automation)、單擊“Finish”按鈕,結(jié)束項目的創(chuàng)建。至此一個基于對話框的應(yīng)用程序框架就搭建好了。主對話框名為CDMSDlg。、項目創(chuàng)建完畢之后,在頭文件stdafx.h中加入下面4行:#import"c:programfilescommonfilessystemadomsado15.dll"no_namespace rename("EOF", "adoEOF&quo

24、t;) #include "icrsint.h"inline void TESTHR(HRESULT x) if FAILED(x) _com_issue_error(x);#define DATEFMTCString("'%s'")第1行中的路徑可能根據(jù)Visual Studio安裝路徑的不同而不同。其中的rename指令,把ADO中的EOF重命名為adoEOF,這是為了避免和其他庫的常量名沖突。注意第3行,這里定義了一個inline函數(shù)TESTHER,它的作用是測試COM函數(shù)的返回值,在這個返回值包含一個錯誤的時候,拋出一個_com_

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

26、是一個在開發(fā)的時候需要注意的細節(jié),后面還會具體提到。2、COM知識準備下面介紹一些關(guān)于COM知識。這部分內(nèi)容是針對那些沒有學習過的COM技術(shù)的讀者,目的是為他們理解ADO提供一些背景知識。COM技術(shù)在微軟公司的應(yīng)用中可以說是無處不在,Windows系統(tǒng)相當多的服務(wù)都以這種方式提供,例如著名的DirectX,還有在這一章中廣泛應(yīng)用的ADO。ADO的底層是OLE DB,他本身則是對OLE DB的一個COM包裝。所以具備一些COM的知識,對使用ADO是很有幫助的,但并不是說必須要精通COM才能使用ADO。事實上,在一般的應(yīng)用中,只需要理解下面這段代碼即可。/DlgViewReport.cpp_Rec

27、ordsetPtr 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->QueryInterfa

28、ce(_uuidof(IADORecordBinding),(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,

29、4, rs.m_sz_buy);m_list.SetItemText(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; 、BSTR和_bstr_t下面的語

30、句聲明了一個_bstr_t型的變量,_bstr_t是對BSTR類型的一個封裝。_bstr_t strSQL(“SELETE *FROM DEVICE_WANTBUY”);對于BSTR,通俗地說,它是COM中使用的字符串,與普通C程序中的字符串的區(qū)別在于:·它一個帶有字符計數(shù)值的字符串。·它的字符計數(shù)值在字符數(shù)組的前面。·它保存的在字符是所謂的“寬字符”(Wide character)。所以,對于一個BSTR而言,下面的語句就是錯的。BSTR str=L”Some words”;正確的做法是:Wchar_t st_=L”Some words”BSTR str;Bst

31、r=SysAllocString(str_)釋放一個SBSTR指針時,則調(diào)用SysFreeString函數(shù)。每次都這樣操控字符串未免太過麻煩,所以Visual C+ 里提供了_bstr_t這個類對BSTR做了封裝,使程序員可以簡單的對這種COM 字符串進行操作了。、IADORecordBinding和Iunkown一個COM組件包含了許多COM對象,程序員通過“接口”來操控這些對象,或者說,這些對象通過提供給程序員的接口來實現(xiàn)自己的功能。下面這行代碼中的IADORecordBind就是一個指向這種接口的指針。IADORecordBingding *picRs=NULL; /Interface

32、Pointer declared(VC+ Extension)每個接口都是從IUnkown這個接口派生出來的。IUkown接口聲明了3個純虛函數(shù):HRESULT QueryInterface(REFID rilid,void*ppvObject);ULONG AddRef();ULONG AddRef();一般來說,不能直接擁有一個IADORecordBind或者IFoo、IBirdISomeInterface諸如此類的接口對象,程序員只能得到一個接口的指針,就像下面的這行代碼:pRst->QueryInterface(_uuidof(IADORecordBingding),(LPVOI

33、D*)&picRs);這行代碼解釋了IUknown接口中QueryInterfae方法的最基本的用法:程序員用它來得到COM對象支持的某個接口的指針。如上例中,pRst時某一個COM對象提供的一個接口指針,程序員從某本書上(比如MSDN)知道了這個對象一定擁有一個IADORecordBinding型的接口,于是調(diào)用上面那行代碼,得到了這個IADORecordBinding接口的指針。然后就可以使用IADORecordBinding接口里聲明的那些方法了。如上所說,一個COM對象,程序員往往不能直接擁有它的實例,而只是它的接口的指針。那什么時候來釋放這個對象呢?這就是AddRef和Rel

34、ease方法的用途。得到了一個接口指針,開始使用一個COM對象,就要調(diào)用它的AddRef方法增加它內(nèi)部的一個引用計數(shù);使用完之后則調(diào)用Release方法減少這個計數(shù)。如果計數(shù)為零,則已經(jīng)說明沒有人使用,這個COM對象就會自己銷毀自己。原則上說,同一個對象提供的不同接口,AddRef和Release的效果都是一樣的。所以在使用完一個COM接口指針之后,一定要這樣:picRs->Release();如果忽略了這一句,就會造成一個COM對象及他所掌握的資源不能被正確釋放。RecordsetPtr和智能指針如上一段所講,使用完一個接口之后忘記調(diào)用Release是一件和糟糕的事,為了彌補這一點,就

35、要寫出一大串嵌套的if語句,降低了程序的易讀性。程序就會拋出異常,而程序員又沒有寫出捕獲這種異常的代碼(往往也不能寫,誰也無法預料自己調(diào)用的某個庫函數(shù)會跑出什么樣的異常),這樣也會跳過某個原本不想跳過的Release。怎么解決這個問題呢?一種方法是用try_finally語句,但是由于現(xiàn)有編譯器的缺陷,包含這個語句的代碼編譯出來的效率較低。這就用到了“智能指針這個工具。_RecordsetPtr pRs=NULL上面這行代碼聲明的變量就是一個智能指針。從他的名字上看,他是對Recordset這種對象的指針進行了包裝。TESTHr(pRst.CreateInstance(_uuidof(Reco

36、rdset);這一句創(chuàng)建了一個Recordset型的COM對象,并對智能指針賦值。在制作所在的函數(shù)體結(jié)束時,智能指針對象從棧中析構(gòu),在它的析構(gòu)函數(shù)里調(diào)用了它所包含接口的Release方法。由它的工作原理看出,它解決了上面的問題棧中對象的析構(gòu)函數(shù)無論如何都是會被調(diào)用的,即使函數(shù)發(fā)生了異常而退出的情況也是如此。除此之外,智能指針可以在接口指針賦值是自動調(diào)用AddRef方法這也是一個容易犯得錯誤。它通過重載運算符,使得它在使用時,和普通的接口指針毫無二致。3、操作日志模塊的設(shè)計、寫日志模塊 通過操作日志模塊,該系統(tǒng)每一次改變數(shù)據(jù)庫數(shù)據(jù)的操作都會在操作日志表格中有相應(yīng)的記錄。這樣可以增強操作人員的責任

37、感,提高系統(tǒng)的安全性,也利于維護數(shù)據(jù)庫數(shù)據(jù)的完整性。此外,一個翔實的操作日志,也給開發(fā)過程中的調(diào)試、除錯帶來很大便利,所以這個模塊的設(shè)計被改在了最前面。先定義一個名為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:_ConnectionPt

38、r m_DBCnt;CString m_user;在這個類中,保存了一個數(shù)據(jù)庫連接的指針m_DBCnt和當前用戶的ID(m_user)。在主對話框CDMSDlg中加入了一個CLogMngr型的成員變量,并在CDMSDlg:OnInitDialog()中調(diào)用其Setup方法進行初始化,設(shè)置好數(shù)據(jù)庫連接指針和用戶名。這樣當程序中某處需要寫信息進行操作日志的時候,只需要調(diào)用這個類的AddLog方法即可。下面是CLogMngr:AddLog內(nèi)部實現(xiàn)的詳細過程。/LogMngr.cpp/向數(shù)據(jù)庫中添加Log記錄的代碼bool CLogMngr:AddLog(LPCSTR op)CTime tm = CT

39、ime:GetCurrentTime();CString 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->Exec

40、ute(sql,NULL,adCmdText);catch(_com_error& e) CString Error = e.ErrorMessage(); AfxMessageBox(e.ErrorMessage();return false; return true;可以看到,它利用了Connection對象的Execute方法,直接執(zhí)行SQL語句,向表中加入了一條包含了操作者、操作時間和操作內(nèi)容3個字段的記錄。直接使用了SQL語句的方法在表比較簡單的時候很快捷,但在表包含比較多的字段的時候,就不太實用了。對日志表,我們暫且先用這種方法。、讀日志模塊在項目資源中加入一個對話框,它包

41、含了一個列表框控件,幾個編輯框和兩個按鈕。這個窗體用以顯示系統(tǒng)所用的日志記錄。它還將實現(xiàn)清空所有記錄的功能(注意為了保證日志記錄的完整性、安全性,不能單獨刪除某條記錄。)在刪除所有記錄時,用SQL語句顯得很方便。但是主意最好不要用那個“Delete * FROM HOWDO”這樣的語句,而是使用下面的“TRUNCATETABLE”語句,它的速度比Delete快。/DlgViewLog.cpp/刪除所有日志記錄的函數(shù)void CDlgViewLog:OnBtnVlrmall() _bstr_t strSQL("TRUNCATE TABLE HOWDO");trym_DBCnt

42、->Execute(strSQL,NULL,adCmdText);catch(_com_error& e) AfxMessageBox(e.ErrorMessage();EndDialog(0); RefreshData();此模塊的時間和數(shù)據(jù)處理與后面的類似,這里暫不敘述。最后整個船體的外表如圖16所示。 圖16 查看日志窗口4、登錄窗口的設(shè)計在CDMSDlg:OnInitDialog()中加入如下一段代碼:/DMSDlg.cpp/彈出登錄界面CDlgLogIn dlg;doif (!dlg.DoModal()EndDialog(0); while (dlg.m_UsrName

43、.GetLength()=0);它的目的是彈出圖17所示的登錄界面,并從中獲取一個有效的用戶名。圖17 登錄界面在得到有效的用戶名(字符串長度非0)后,程序用如下的代碼嘗試連接數(shù)據(jù)庫,初始化成員變量(Connection指針和ClogMngr的實例)。在連接成功后,寫登錄記錄進入操作日志。/ DMSDlg.cpp/建立數(shù)據(jù)庫連接,初始化成員變量/登錄庫,如失敗,則關(guān)閉程序trym_DBCnt.CreateInstance(_uuidof(Connection);CString sql_;sql_.Format("DSN=DMS;UID=%s;PWD=%s",dlg.m_Us

44、rName,dlg.m_UsrPwd);_bstr_t sql=sql_;m_DBCnt->Open(sql,"","",-1);m_logMngr.Setup(m_DBCnt,dlg.m_UsrName);m_logMngr.AddLog("登錄數(shù)據(jù)庫");catch(_com_error& e) AfxMessageBox(e.ErrorMessage();this->EndDialog(0); 最后別忘了在程序結(jié)束的時候關(guān)閉數(shù)據(jù)庫連接。/ DMSDlg.cpp/void CDMSDlg:OnDestroy()

45、 CDialog:OnDestroy(); m_DBCnt->Close();5、主對話框的設(shè)計登錄完成后,顯示出主對話框。它的界面如圖18所示,單擊某個按鈕就能彈出某個功能的界面。注意到按鈕的排布時按照所處的模塊分類的。 圖18 主對話框界面 以其中“設(shè)備代碼”按鈕為例,說明他的事件處理函數(shù)。代碼如下: /DMSDlg.cpp /顯示設(shè)備代碼管理界面 void CDMSDlg:OnBtnDevcode() CDlgDevcode dlg;dlg.Setup(m_DBCnt,&m_logMngr);this->ShowWindow(SW_HIDE);dlg.DoModal(

46、);this->ShowWindow(SW_SHOW);從上面的代碼看出,當單擊“設(shè)備代碼”按鈕時,程序構(gòu)造一個CDlgDevcode型對話框?qū)嵗ㄟ^它的Setup函數(shù)賦給它一個數(shù)據(jù)庫連接指針和一個日志管理對象實例的指針,然后主對話框隱藏,直到子對話框事物處理結(jié)束。6、設(shè)備代碼管理窗口的建立設(shè)備代碼表格(device_code)經(jīng)常被其他表格引用,如獲取合法編碼、由設(shè)備編碼號查找設(shè)備名稱等。所以自日志模塊和主對話框完成之后,先建立這個表格的管理模塊。對話框類名為CDlgDevcode,設(shè)計如圖19所示。圖19 設(shè)備代碼管理窗口這里用一個列表框控件顯示讀取的數(shù)據(jù)記錄。在CDlgDevco

47、de:OnInitDialog()中對這個控件(m_list)進行初始化(分割列、設(shè)置列寬、設(shè)置風格等)。/DlgDevcode.cpp/對話框的初始化BOOL CDlgDevcode:OnInitDialog() CDialog:OnInitDialog();m_list.InsertColumn(0,"設(shè)備號");m_list.InsertColumn(1,"設(shè)備名");RECT rect;m_list.GetWindowRect(&rect);int wid = rect.right - rect.left;m_list.SetColumn

48、Width(0,wid/2);m_list.SetColumnWidth(1,wid/2);m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT);RefreshData();return TRUE;注意:其中一行代碼:m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT),定義了當表格某整行被選中時,將此行的完整數(shù)據(jù)在表格控件的右側(cè)顯示出來。以后的各個模塊都用到了這個方法,這部分的代碼如下:/DlgDevcode.cpp/消息映射部分BEGIN_MESSAGE_MAP(CDlgDevcode, CDialog)/AFX_

49、MSG_MAP(CDlgDevcode) ON_NOTIFY(NM_CLICK,IDC_LIST_DEVCODE,OnClickListDevcode)/AFX_MSG_MAPEND_MESSAGE_MAP()/事件處理部分void CDlgDevcode:OnClickListDevcode(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);*

50、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 = _FILE_;#endif/ CDlgDevcode dialogCDlgDevcode:CDlgDevcode(CWnd* pParent /*=NULL*/

51、): 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_DATA_MAP(CDlgDevcode)DDX_Control(pDX, IDC_LIST_DEVCODE, m_l

52、ist);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_DCADD, OnBtnDcadd)ON_BN_CLICKED(IDC_BTN_DCDEL, OnBtnDcdel)ON_

53、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 = 0;tryMySet.CreateInstance(_uuidof(Recordset); MyS

溫馨提示

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

評論

0/150

提交評論