




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、數(shù)據(jù)庫(kù)課程設(shè)計(jì)報(bào)告題目:倉(cāng)庫(kù)管理系統(tǒng)組長(zhǎng):王 寧(P071513228)組員:胡樂樂(P071513227)徐 建(P071513237) 葛 東(P071513256) 張 超(P071513267)指導(dǎo)教師:曹永春計(jì)算機(jī)科學(xué)與信息工程學(xué)院倉(cāng)庫(kù)管理系統(tǒng)一、設(shè)計(jì)目標(biāo)企業(yè)的倉(cāng)庫(kù)物資管理往往復(fù)雜、繁瑣。本系統(tǒng)主要針對(duì)企業(yè)生產(chǎn)所需要的各種設(shè)備而設(shè)計(jì),實(shí)施驗(yàn)收入庫(kù)并填寫入庫(kù)單和入庫(kù)登記;企業(yè)各個(gè)部門根據(jù)所需要提出物質(zhì)申請(qǐng),計(jì)劃員根據(jù)整個(gè)企業(yè)的需求開出物資設(shè)備出庫(kù)單,倉(cāng)庫(kù)管理員根據(jù)出庫(kù)單核對(duì)發(fā)放設(shè)備;設(shè)備使用完畢需要及時(shí)歸還入庫(kù),填寫還入庫(kù)單。系統(tǒng)還根據(jù)需要按照月、季、年進(jìn)行統(tǒng)計(jì)分析,產(chǎn)生相應(yīng)報(bào)表。根據(jù)
2、系統(tǒng)功能的要求,倉(cāng)庫(kù)管理系統(tǒng)可以分為日志管理、入庫(kù)、出庫(kù)、還庫(kù)、查詢、報(bào)表等主要模塊。企業(yè)的物資供應(yīng)管理往往是很復(fù)雜、繁瑣的。由于掌握的物資種類眾多,訂貨、管理、發(fā)放的渠道各有差異,各個(gè)企業(yè)之間的管理機(jī)制不盡相同,各類統(tǒng)計(jì)計(jì)劃報(bào)表繁多,因此物資管理必須實(shí)現(xiàn)計(jì)算機(jī)化,而且必須根據(jù)企業(yè)的具體情況制定相應(yīng)的方案以便提高工作效率。根據(jù)當(dāng)前的企業(yè)管理體制,一般物資供應(yīng)管理系統(tǒng),總是根據(jù)所掌握的物資類別,相應(yīng)分成幾個(gè)科室來(lái)進(jìn)行物資的計(jì)劃、訂貨、核銷托收、驗(yàn)收入庫(kù)。根據(jù)企業(yè)各個(gè)部門的來(lái)發(fā)送物資設(shè)備,并隨時(shí)按期進(jìn)行庫(kù)存盤點(diǎn)、做臺(tái)帳、根據(jù)企業(yè)自身領(lǐng)導(dǎo)和自身管理的需要按月、季、年進(jìn)行統(tǒng)計(jì)分析,產(chǎn)生相應(yīng)的報(bào)表。為了
3、加強(qiáng)相應(yīng)物資、設(shè)備的管理,要定期掌握其儲(chǔ)備、消耗情況,根據(jù)計(jì)劃定額和實(shí)際消耗定額的比較,進(jìn)行定額管理。倉(cāng)庫(kù)管理的物資在本章中主要是企業(yè)生產(chǎn)所需的各種設(shè)備。進(jìn)貨時(shí)檢查合同確認(rèn)為有效托收之后,進(jìn)行驗(yàn)收入庫(kù)、填寫入庫(kù)單和入庫(kù)登記。企業(yè)各個(gè)部門根據(jù)所需要的物資設(shè)備總額和部門生產(chǎn)活動(dòng)所需要提出物資需求申請(qǐng),計(jì)劃員根據(jù)企業(yè)的需求開出物資設(shè)備出庫(kù)單,倉(cāng)庫(kù)管理員根據(jù)出庫(kù)單核對(duì)發(fā)放設(shè)備。設(shè)備使用完畢需要及時(shí)歸還入庫(kù),填寫還入庫(kù)單。系統(tǒng)還根據(jù)需要按照月、季、年進(jìn)行統(tǒng)計(jì)分析,產(chǎn)生相應(yīng)報(bào)表。為了跟好的理解該系統(tǒng)和讀懂該系統(tǒng)的源代碼,讀者應(yīng)對(duì)以下的知識(shí)點(diǎn)有所了解:·Access數(shù)據(jù)庫(kù)操作的基礎(chǔ)知識(shí)。·
4、;ODBC數(shù)據(jù)源基礎(chǔ)知識(shí)。·基本的SQL語(yǔ)句,如添加、查詢、修改和刪除記錄語(yǔ)句。·Visual C+界面設(shè)計(jì)和關(guān)于數(shù)據(jù)庫(kù)的基礎(chǔ)知識(shí)。二、系統(tǒng)設(shè)計(jì)倉(cāng)庫(kù)管理的特點(diǎn)是信息處理量比較大,所管理的物資設(shè)備種類繁多,而且入庫(kù)單、出庫(kù)單、需求單等單據(jù)的發(fā)生量特別大,關(guān)聯(lián)信息多,查詢和統(tǒng)計(jì)的方式各不相同,在管理上實(shí)現(xiàn)起來(lái)有一定的困難。在管理的過程中經(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)表的格式。·刪除不必要的管理
5、冗余,實(shí)現(xiàn)管理規(guī)范化、科學(xué)化。·程序代碼標(biāo)準(zhǔn)化,軟件統(tǒng)一化,確保軟件的可維護(hù)性和實(shí)用性。·界面盡量簡(jiǎn)單化,做到實(shí)用、方便,盡量滿足企業(yè)中不同層次員工的需要。·建立操作日志,系統(tǒng)自動(dòng)記錄所進(jìn)行的各種操作。1、系統(tǒng)功能分析 本例中的倉(cāng)庫(kù)管理系統(tǒng)需要完成的功能主要有以下幾點(diǎn): ·倉(cāng)庫(kù)管理各種信息的輸入,包括入庫(kù)、出庫(kù)、還庫(kù)、需求信息的輸入等。 ·倉(cāng)庫(kù)管理各種信息的查詢、修改和維護(hù)。 ·設(shè)備采購(gòu)報(bào)表的生成。 ·在庫(kù)存管理中加入最高儲(chǔ)備和最低儲(chǔ)備字段,對(duì)倉(cāng)庫(kù)中的物資設(shè)備實(shí)現(xiàn)監(jiān)控和報(bào)警。 ·企業(yè)各部門的物資需求的管理。
6、83;操作日志的管理。 ·倉(cāng)庫(kù)管理系統(tǒng)的使用幫助。2、系統(tǒng)功能模塊設(shè)計(jì) 在系統(tǒng)功能分析的基礎(chǔ)上,結(jié)合Visual C+程序編制的特點(diǎn),得到如圖1所示的系統(tǒng)功能模塊圖。倉(cāng)庫(kù)管理系統(tǒng)系統(tǒng)模塊輸入模塊維護(hù)模塊查看模塊報(bào)表模塊幫助模塊日志管理需求模塊還庫(kù)模塊出庫(kù)模塊入庫(kù)模塊圖1 系統(tǒng)功能模塊圖 系統(tǒng)主要界面及流程如下所示。 程序開始運(yùn)行之后先出現(xiàn)如圖2的登陸界面。成功輸入用戶名和密碼后將進(jìn)入主對(duì)話框。圖2 登陸界面單擊“設(shè)備代碼”按鈕進(jìn)入設(shè)備代碼表(device_code)的管理。單擊“庫(kù)存信息”按鈕進(jìn)入現(xiàn)有庫(kù)存表(device)的管理。單擊“設(shè)備入庫(kù)”按鈕開始設(shè)備入庫(kù)操作,若成功,則在設(shè)備
7、入庫(kù)表(device_in)中增加一條記錄,同時(shí)修改現(xiàn)有的庫(kù)存表(device)中的相關(guān)數(shù)據(jù)。單擊“設(shè)備出庫(kù)”按鈕開始設(shè)備出庫(kù)操作,如圖3所示。若成功,則在設(shè)備出庫(kù)表(device)中的相關(guān)數(shù)據(jù)。 圖3 設(shè)備出庫(kù)登記窗口單擊下方的“出庫(kù)信息”按鈕進(jìn)入設(shè)備出庫(kù)表(device_out)的管理。如圖4所示。圖4 出庫(kù)信息管理界面單擊“設(shè)備還庫(kù)”按鈕開始設(shè)備還庫(kù)操作。若成功,則在設(shè)備還庫(kù)表(device_return)中增加一條記錄,同時(shí)修改現(xiàn)有庫(kù)存表(device)中的相關(guān)數(shù)據(jù)。單擊下方的“還庫(kù)信息”按鈕進(jìn)入設(shè)備還庫(kù)表(device_return)的管理。單擊“設(shè)備需求”進(jìn)入設(shè)備需求登記的界面,如
8、圖5所示。用戶在這里填寫設(shè)備需求。若成功,則在設(shè)備需求表(device_need)中增加一條設(shè)備需求記錄。圖5 設(shè)備需求登記窗口單擊下方“需求信息”按鈕進(jìn)入設(shè)備需求表(device_need)的管理。如圖6所示。單擊“操作日志”按鈕查看目前的所有操作日志記錄,在里面還可以刪除所有日志記錄。單擊“幫助”按鈕進(jìn)入聯(lián)機(jī)幫助。單擊“關(guān)于”按鈕查看程序信息圖6 需求信息管理窗口三、數(shù)據(jù)庫(kù)設(shè)計(jì)1、數(shù)據(jù)庫(kù)需求分析在仔細(xì)調(diào)查企倉(cāng)庫(kù)物資設(shè)備管理過程的基礎(chǔ)上,得到本系統(tǒng)所處理的數(shù)據(jù)流程,如圖7所示。 設(shè)備入庫(kù)設(shè)備采購(gòu)設(shè)備還庫(kù)設(shè)備出庫(kù)倉(cāng)庫(kù)現(xiàn)有庫(kù)存各部門需求企業(yè)生產(chǎn)計(jì)劃匯總圖 7 數(shù)據(jù)流程圖針對(duì)本實(shí)例,通過對(duì)企業(yè)倉(cāng)庫(kù)
9、管理的內(nèi)容和數(shù)據(jù)流程的分析,設(shè)計(jì)的數(shù)據(jù)項(xiàng)和數(shù)據(jù)結(jié)構(gòu)如下:·設(shè)備代碼信息:其數(shù)據(jù)項(xiàng)有設(shè)備號(hào)、設(shè)備名稱·現(xiàn)有庫(kù)存信息:其數(shù)據(jù)項(xiàng)有現(xiàn)有設(shè)備、現(xiàn)有數(shù)目、總數(shù)目、最大庫(kù)存和最小庫(kù)存等·設(shè)備使用信息:其數(shù)據(jù)項(xiàng)有使用的設(shè)備、使用部門、數(shù)目、使用時(shí)間和出庫(kù)時(shí)狀態(tài)等·設(shè)備采購(gòu)信息:其數(shù)據(jù)項(xiàng)有采購(gòu)的設(shè)備、采購(gòu)員、供應(yīng)商、采購(gòu)數(shù)目和采購(gòu)時(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ì)階段是在需求分析的基礎(chǔ)上,設(shè)計(jì)出能滿足用戶需求的各
10、種實(shí)體,以及它們之間的關(guān)系,為后面的邏輯結(jié)構(gòu)設(shè)計(jì)打下基礎(chǔ)。本實(shí)例根據(jù)上面得設(shè)計(jì)規(guī)劃出實(shí)體有庫(kù)存實(shí)體,入庫(kù)實(shí)體、出庫(kù)實(shí)體、采購(gòu)實(shí)體、還庫(kù)實(shí)體和需求實(shí)體。各實(shí)體的E-R圖及其關(guān)系描述如下:現(xiàn)有庫(kù)存現(xiàn)有庫(kù)存現(xiàn)有庫(kù)存現(xiàn)有庫(kù)存設(shè)備號(hào)圖8 庫(kù)存實(shí)體E-R圖入庫(kù)供應(yīng)商信息采購(gòu)價(jià)格數(shù)量采購(gòu)員設(shè)備號(hào)圖9 入庫(kù)實(shí)體E-R圖出庫(kù)使用部門數(shù)量、時(shí)間經(jīng)手人設(shè)備號(hào)圖10 出庫(kù)實(shí)體E-R圖部門需求需求部門需求數(shù)量需求時(shí)間設(shè)備號(hào) 圖11 部門需求實(shí)體E-R圖設(shè)備還庫(kù)還庫(kù)時(shí)間人還庫(kù)數(shù)量經(jīng)手人設(shè)備號(hào)圖12 還庫(kù)實(shí)體E-R圖計(jì)劃采購(gòu)庫(kù)存信息供應(yīng)信息時(shí)間設(shè)備號(hào) 圖13 計(jì)劃采購(gòu)實(shí)體E-R圖入庫(kù) 現(xiàn)有庫(kù)存 出庫(kù) 還庫(kù) 部門需求設(shè)備采購(gòu)
11、圖 14 實(shí)體和實(shí)體之間的關(guān)系E-R圖3、數(shù)據(jù)庫(kù)邏輯結(jié)構(gòu)設(shè)計(jì)在上面的實(shí)體以及實(shí)體之間的關(guān)系的基礎(chǔ)上,形成數(shù)據(jù)庫(kù)中的表格和各個(gè)表格之間的關(guān)系。倉(cāng)庫(kù)管理系統(tǒng)數(shù)據(jù)庫(kù)中的各個(gè)表格的設(shè)計(jì)結(jié)果如下面的幾個(gè)表格所示。每個(gè)表格表示在數(shù)據(jù)庫(kù)中的一個(gè)表。 列名 數(shù)據(jù)類型 可否為空 說(shuō)明 CodeVARCHAR2(6) NOTNULL 設(shè)備號(hào)(主鍵) NameVARVHAR2(20) NULL 設(shè)備名稱設(shè)備代碼表device_code 列名 數(shù)據(jù)類型 可否為空 說(shuō)明CodeVARCHAR2(6)NOTNULL設(shè)備號(hào)In_dateDATENOTNULL入庫(kù)時(shí)間(主鍵)ProviderVARCHAR2(20)NULL供
12、應(yīng)商TelenoVARCHAR2(20)NULL供應(yīng)商電話In_numberNUMBER(6)NULL入庫(kù)數(shù)量PriceNUMBER(6)NULL價(jià)格BuyerVARCHAR2(10)NULL采購(gòu)設(shè)備庫(kù)表device_in列名 數(shù)據(jù)類型 可否為空 說(shuō)明CodeVARCHAR2(6)NOTNULL設(shè)備號(hào)DepartmentVARCHAR2(20)NULL使用部門Out_dateDATENULL出庫(kù)時(shí)間(主鍵)Out_stateNUMBER(1)NULL出庫(kù)狀況Out_personVARCHAR2(10)NULL經(jīng)手人Out_numberNUMBER2(10)NOTNULL出庫(kù)數(shù)量TakerVAR
13、CHAR2(10)NULL領(lǐng)取UsageVARCHAR2(20)NULL用途設(shè)備出庫(kù)表device_out列名數(shù)據(jù)類型可否為空說(shuō)明codeVARCHAR2(6)NOT NULL設(shè)備號(hào)(主鍵)now_numberNUMBER(6)NULL現(xiàn)有庫(kù)存high_numberNUMBER(6)NULL最大庫(kù)存low_numberNUMBER(6)NULL最小庫(kù)存total_numberNUMBER(6)NULL總數(shù)現(xiàn)有數(shù)據(jù)庫(kù)表device列名數(shù)據(jù)類型可否為空說(shuō)明codeVARCHAR2(6)NOT NULL設(shè)備號(hào)departmentVARCHAR2(20)NOT NULL部門名稱need_numberN
14、UMBER(6)NULL需要數(shù)量begin_dateDATENULL需求開始時(shí)間end_dateDATEMULL需求結(jié)束時(shí)間 設(shè)備需求表 device_need列名數(shù)據(jù)類型可否為空說(shuō)明codeVARCHAR2(6)NOT NULL設(shè)備號(hào)return_dateDATENULL還庫(kù)時(shí)間(主鍵)keeperVARCHAR2(10)NULL倉(cāng)庫(kù)管理員return_numberNUMBER(6)NULL歸還數(shù)量return_personVARCHAR2(10)NULL歸還人 設(shè)備還庫(kù)表device_return列名數(shù)據(jù)類型可否為空說(shuō)明do_userVARCHAR2(10)NOT NULL操作員do_wh
15、atVARCHAR2(40)NOT NULL操作內(nèi)容do_dateDATENOT NULL操作時(shí)間操作日志表howdo列名數(shù)據(jù)類型可否為空說(shuō)明codeVARCHAR2(6)NOT NULL設(shè)備號(hào)now_numberNUMBER(6)NULL現(xiàn)有庫(kù)存total_numberNUMBER(6)NULL總庫(kù)存max_numberNUMBER(6)NULL購(gòu)買數(shù)量providerVARCHAR(2)NULL供應(yīng)商priceNUMBER(6)NULL價(jià)格buy_dateDATENULL計(jì)劃采購(gòu)時(shí)間(主鍵)設(shè)備采購(gòu)計(jì)劃表 device_wantbuy4、數(shù)據(jù)庫(kù)結(jié)構(gòu)的實(shí)現(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è)備入庫(kù)表 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è)備出庫(kù)表 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)有庫(kù)存表 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è)備還庫(kù)表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è)備采購(gòu)計(jì)劃表 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)實(shí)現(xiàn)1、創(chuàng)建應(yīng)用程序此倉(cāng)庫(kù)系統(tǒng)應(yīng)用程序的創(chuàng)建步驟如下:、選擇菜單“File|New”中的“新建項(xiàng)目”選項(xiàng)卡中“MFC AppWizard(exe)”,設(shè)置合適的目錄和項(xiàng)目名,比如“E:Projects”目錄下的“DMS”項(xiàng)目。、創(chuàng)建一個(gè)對(duì)話框應(yīng)用程序(“Dialog Based”),單擊“Next”按鈕。、由于
23、在這個(gè)項(xiàng)目中將要使用ADO,所以在MFC AppWizard 的第2步,需要選中“Automation”選項(xiàng),使應(yīng)用程序能夠支持自動(dòng)化對(duì)象,如圖15所示。圖15 使應(yīng)用程序支持自動(dòng)化(Automation)、單擊“Finish”按鈕,結(jié)束項(xiàng)目的創(chuàng)建。至此一個(gè)基于對(duì)話框的應(yīng)用程序框架就搭建好了。主對(duì)話框名為CDMSDlg。、項(xiàng)目創(chuàng)建完畢之后,在頭文件stdafx.h中加入下面4行:#import"c:programfilescommonfilessystemadomsado15.dll"no_namespace rename("EOF", "ad
24、oEOF") #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,這是為了避免和其他庫(kù)的常量名沖突。注意第3行,這里定義了一個(gè)inline函數(shù)TESTHER,它的作用是測(cè)試COM函數(shù)的返回值,在這個(gè)返回值包含一個(gè)錯(cuò)誤的時(shí)候,拋
25、出一個(gè)_com_error型的異常。ADO作為一個(gè)COM組件接口,它的許多函數(shù)都會(huì)返回一個(gè)HRESULT型的值作為結(jié)果。如果在每一步都用SUCCEEDED或FAILED宏測(cè)試返回值的話,將會(huì)不勝其煩,還有可能制造出一連串嵌套的if語(yǔ)句這樣不美觀的代碼。這個(gè)函數(shù)簡(jiǎn)化了這種驗(yàn)證操作,利用C+的異常處理機(jī)制,使代碼顯得緊湊而高效,為后面的工作帶來(lái)很大方便。第4行定義了一個(gè)宏。這是不同的后臺(tái)數(shù)據(jù)庫(kù)對(duì)SQL語(yǔ)句中日期的用法要求不同引起的。比如Access數(shù)據(jù)庫(kù)要求SQL語(yǔ)句中的日期用兩個(gè)#字符括起,而其他的數(shù)據(jù)庫(kù)可能需要使用單引號(hào)或者雙引號(hào)。所以在這里定義了這個(gè)DATEFMT宏,為了方便程序在不同的后臺(tái)
26、數(shù)據(jù)庫(kù)鍵切換。這是一個(gè)在開發(fā)的時(shí)候需要注意的細(xì)節(jié),后面還會(huì)具體提到。2、COM知識(shí)準(zhǔn)備下面介紹一些關(guān)于COM知識(shí)。這部分內(nèi)容是針對(duì)那些沒有學(xué)習(xí)過的COM技術(shù)的讀者,目的是為他們理解ADO提供一些背景知識(shí)。COM技術(shù)在微軟公司的應(yīng)用中可以說(shuō)是無(wú)處不在,Windows系統(tǒng)相當(dāng)多的服務(wù)都以這種方式提供,例如著名的DirectX,還有在這一章中廣泛應(yīng)用的ADO。ADO的底層是OLE DB,他本身則是對(duì)OLE DB的一個(gè)COM包裝。所以具備一些COM的知識(shí),對(duì)使用ADO是很有幫助的,但并不是說(shuō)必須要精通COM才能使用ADO。事實(shí)上,在一般的應(yīng)用中,只需要理解下面這段代碼即可。/DlgViewReport
27、.cpp_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->Quer
28、yInterface(_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.SetItem
29、Text(i, 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和_bs
30、tr_t下面的語(yǔ)句聲明了一個(gè)_bstr_t型的變量,_bstr_t是對(duì)BSTR類型的一個(gè)封裝。_bstr_t strSQL(“SELETE *FROM DEVICE_WANTBUY”);對(duì)于BSTR,通俗地說(shuō),它是COM中使用的字符串,與普通C程序中的字符串的區(qū)別在于:·它一個(gè)帶有字符計(jì)數(shù)值的字符串。·它的字符計(jì)數(shù)值在字符數(shù)組的前面。·它保存的在字符是所謂的“寬字符”(Wide character)。所以,對(duì)于一個(gè)BSTR而言,下面的語(yǔ)句就是錯(cuò)的。BSTR str=L”Some words”;正確的做法是:Wchar_t st_=L”Some words”BSTR
31、 str;Bstr=SysAllocString(str_)釋放一個(gè)SBSTR指針時(shí),則調(diào)用SysFreeString函數(shù)。每次都這樣操控字符串未免太過麻煩,所以Visual C+ 里提供了_bstr_t這個(gè)類對(duì)BSTR做了封裝,使程序員可以簡(jiǎn)單的對(duì)這種COM 字符串進(jìn)行操作了。、IADORecordBinding和Iunkown一個(gè)COM組件包含了許多COM對(duì)象,程序員通過“接口”來(lái)操控這些對(duì)象,或者說(shuō),這些對(duì)象通過提供給程序員的接口來(lái)實(shí)現(xiàn)自己的功能。下面這行代碼中的IADORecordBind就是一個(gè)指向這種接口的指針。IADORecordBingding *picRs=NULL; /In
32、terface Pointer declared(VC+ Extension)每個(gè)接口都是從IUnkown這個(gè)接口派生出來(lái)的。IUkown接口聲明了3個(gè)純虛函數(shù):HRESULT QueryInterface(REFID rilid,void*ppvObject);ULONG AddRef();ULONG AddRef();一般來(lái)說(shuō),不能直接擁有一個(gè)IADORecordBind或者IFoo、IBirdISomeInterface諸如此類的接口對(duì)象,程序員只能得到一個(gè)接口的指針,就像下面的這行代碼:pRst->QueryInterface(_uuidof(IADORecordBingding
33、),(LPVOID*)&picRs);這行代碼解釋了IUknown接口中QueryInterfae方法的最基本的用法:程序員用它來(lái)得到COM對(duì)象支持的某個(gè)接口的指針。如上例中,pRst時(shí)某一個(gè)COM對(duì)象提供的一個(gè)接口指針,程序員從某本書上(比如MSDN)知道了這個(gè)對(duì)象一定擁有一個(gè)IADORecordBinding型的接口,于是調(diào)用上面那行代碼,得到了這個(gè)IADORecordBinding接口的指針。然后就可以使用IADORecordBinding接口里聲明的那些方法了。如上所說(shuō),一個(gè)COM對(duì)象,程序員往往不能直接擁有它的實(shí)例,而只是它的接口的指針。那什么時(shí)候來(lái)釋放這個(gè)對(duì)象呢?這就是Ad
34、dRef和Release方法的用途。得到了一個(gè)接口指針,開始使用一個(gè)COM對(duì)象,就要調(diào)用它的AddRef方法增加它內(nèi)部的一個(gè)引用計(jì)數(shù);使用完之后則調(diào)用Release方法減少這個(gè)計(jì)數(shù)。如果計(jì)數(shù)為零,則已經(jīng)說(shuō)明沒有人使用,這個(gè)COM對(duì)象就會(huì)自己銷毀自己。原則上說(shuō),同一個(gè)對(duì)象提供的不同接口,AddRef和Release的效果都是一樣的。所以在使用完一個(gè)COM接口指針之后,一定要這樣:picRs->Release();如果忽略了這一句,就會(huì)造成一個(gè)COM對(duì)象及他所掌握的資源不能被正確釋放。RecordsetPtr和智能指針如上一段所講,使用完一個(gè)接口之后忘記調(diào)用Release是一件和糟糕的事,為
35、了彌補(bǔ)這一點(diǎn),就要寫出一大串嵌套的if語(yǔ)句,降低了程序的易讀性。程序就會(huì)拋出異常,而程序員又沒有寫出捕獲這種異常的代碼(往往也不能寫,誰(shuí)也無(wú)法預(yù)料自己調(diào)用的某個(gè)庫(kù)函數(shù)會(huì)跑出什么樣的異常),這樣也會(huì)跳過某個(gè)原本不想跳過的Release。怎么解決這個(gè)問題呢?一種方法是用try_finally語(yǔ)句,但是由于現(xiàn)有編譯器的缺陷,包含這個(gè)語(yǔ)句的代碼編譯出來(lái)的效率較低。這就用到了“智能指針這個(gè)工具。_RecordsetPtr pRs=NULL上面這行代碼聲明的變量就是一個(gè)智能指針。從他的名字上看,他是對(duì)Recordset這種對(duì)象的指針進(jìn)行了包裝。TESTHr(pRst.CreateInstance(_uui
36、dof(Recordset);這一句創(chuàng)建了一個(gè)Recordset型的COM對(duì)象,并對(duì)智能指針賦值。在制作所在的函數(shù)體結(jié)束時(shí),智能指針對(duì)象從棧中析構(gòu),在它的析構(gòu)函數(shù)里調(diào)用了它所包含接口的Release方法。由它的工作原理看出,它解決了上面的問題棧中對(duì)象的析構(gòu)函數(shù)無(wú)論如何都是會(huì)被調(diào)用的,即使函數(shù)發(fā)生了異常而退出的情況也是如此。除此之外,智能指針可以在接口指針賦值是自動(dòng)調(diào)用AddRef方法這也是一個(gè)容易犯得錯(cuò)誤。它通過重載運(yùn)算符,使得它在使用時(shí),和普通的接口指針毫無(wú)二致。3、操作日志模塊的設(shè)計(jì)、寫日志模塊 通過操作日志模塊,該系統(tǒng)每一次改變數(shù)據(jù)庫(kù)數(shù)據(jù)的操作都會(huì)在操作日志表格中有相應(yīng)的記錄。這樣可以增
37、強(qiáng)操作人員的責(zé)任感,提高系統(tǒng)的安全性,也利于維護(hù)數(shù)據(jù)庫(kù)數(shù)據(jù)的完整性。此外,一個(gè)翔實(shí)的操作日志,也給開發(fā)過程中的調(diào)試、除錯(cuò)帶來(lái)很大便利,所以這個(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:_Conn
38、ectionPtr m_DBCnt;CString m_user;在這個(gè)類中,保存了一個(gè)數(shù)據(jù)庫(kù)連接的指針m_DBCnt和當(dāng)前用戶的ID(m_user)。在主對(duì)話框CDMSDlg中加入了一個(gè)CLogMngr型的成員變量,并在CDMSDlg:OnInitDialog()中調(diào)用其Setup方法進(jìn)行初始化,設(shè)置好數(shù)據(jù)庫(kù)連接指針和用戶名。這樣當(dāng)程序中某處需要寫信息進(jìn)行操作日志的時(shí)候,只需要調(diào)用這個(gè)類的AddLog方法即可。下面是CLogMngr:AddLog內(nèi)部實(shí)現(xiàn)的詳細(xì)過程。/LogMngr.cpp/向數(shù)據(jù)庫(kù)中添加Log記錄的代碼bool CLogMngr:AddLog(LPCSTR op)CTime
39、 tm = CTime: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-
40、>Execute(sql,NULL,adCmdText);catch(_com_error& e) CString Error = e.ErrorMessage(); AfxMessageBox(e.ErrorMessage();return false; return true;可以看到,它利用了Connection對(duì)象的Execute方法,直接執(zhí)行SQL語(yǔ)句,向表中加入了一條包含了操作者、操作時(shí)間和操作內(nèi)容3個(gè)字段的記錄。直接使用了SQL語(yǔ)句的方法在表比較簡(jiǎn)單的時(shí)候很快捷,但在表包含比較多的字段的時(shí)候,就不太實(shí)用了。對(duì)日志表,我們暫且先用這種方法。、讀日志模塊在項(xiàng)目資源中加入
41、一個(gè)對(duì)話框,它包含了一個(gè)列表框控件,幾個(gè)編輯框和兩個(gè)按鈕。這個(gè)窗體用以顯示系統(tǒng)所用的日志記錄。它還將實(shí)現(xiàn)清空所有記錄的功能(注意為了保證日志記錄的完整性、安全性,不能單獨(dú)刪除某條記錄。)在刪除所有記錄時(shí),用SQL語(yǔ)句顯得很方便。但是主意最好不要用那個(gè)“Delete * FROM HOWDO”這樣的語(yǔ)句,而是使用下面的“TRUNCATETABLE”語(yǔ)句,它的速度比Delete快。/DlgViewLog.cpp/刪除所有日志記錄的函數(shù)void CDlgViewLog:OnBtnVlrmall() _bstr_t strSQL("TRUNCATE TABLE HOWDO");tr
42、ym_DBCnt->Execute(strSQL,NULL,adCmdText);catch(_com_error& e) AfxMessageBox(e.ErrorMessage();EndDialog(0); RefreshData();此模塊的時(shí)間和數(shù)據(jù)處理與后面的類似,這里暫不敘述。最后整個(gè)船體的外表如圖16所示。 圖16 查看日志窗口4、登錄窗口的設(shè)計(jì)在CDMSDlg:OnInitDialog()中加入如下一段代碼:/DMSDlg.cpp/彈出登錄界面CDlgLogIn dlg;doif (!dlg.DoModal()EndDialog(0); while (dlg.m
43、_UsrName.GetLength()=0);它的目的是彈出圖17所示的登錄界面,并從中獲取一個(gè)有效的用戶名。圖17 登錄界面在得到有效的用戶名(字符串長(zhǎng)度非0)后,程序用如下的代碼嘗試連接數(shù)據(jù)庫(kù),初始化成員變量(Connection指針和ClogMngr的實(shí)例)。在連接成功后,寫登錄記錄進(jìn)入操作日志。/ DMSDlg.cpp/建立數(shù)據(jù)庫(kù)連接,初始化成員變量/登錄庫(kù),如失敗,則關(guān)閉程序trym_DBCnt.CreateInstance(_uuidof(Connection);CString sql_;sql_.Format("DSN=DMS;UID=%s;PWD=%s",
44、dlg.m_UsrName,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ù)庫(kù)");catch(_com_error& e) AfxMessageBox(e.ErrorMessage();this->EndDialog(0); 最后別忘了在程序結(jié)束的時(shí)候關(guān)閉數(shù)據(jù)庫(kù)連接。/ DMSDlg.cpp/void CDMSDlg:OnD
45、estroy() CDialog:OnDestroy(); m_DBCnt->Close();5、主對(duì)話框的設(shè)計(jì)登錄完成后,顯示出主對(duì)話框。它的界面如圖18所示,單擊某個(gè)按鈕就能彈出某個(gè)功能的界面。注意到按鈕的排布時(shí)按照所處的模塊分類的。 圖18 主對(duì)話框界面 以其中“設(shè)備代碼”按鈕為例,說(shuō)明他的事件處理函數(shù)。代碼如下: /DMSDlg.cpp /顯示設(shè)備代碼管理界面 void CDMSDlg:OnBtnDevcode() CDlgDevcode dlg;dlg.Setup(m_DBCnt,&m_logMngr);this->ShowWindow(SW_HIDE);dlg.
46、DoModal();this->ShowWindow(SW_SHOW);從上面的代碼看出,當(dāng)單擊“設(shè)備代碼”按鈕時(shí),程序構(gòu)造一個(gè)CDlgDevcode型對(duì)話框?qū)嵗?,通過它的Setup函數(shù)賦給它一個(gè)數(shù)據(jù)庫(kù)連接指針和一個(gè)日志管理對(duì)象實(shí)例的指針,然后主對(duì)話框隱藏,直到子對(duì)話框事物處理結(jié)束。6、設(shè)備代碼管理窗口的建立設(shè)備代碼表格(device_code)經(jīng)常被其他表格引用,如獲取合法編碼、由設(shè)備編碼號(hào)查找設(shè)備名稱等。所以自日志模塊和主對(duì)話框完成之后,先建立這個(gè)表格的管理模塊。對(duì)話框類名為CDlgDevcode,設(shè)計(jì)如圖19所示。圖19 設(shè)備代碼管理窗口這里用一個(gè)列表框控件顯示讀取的數(shù)據(jù)記錄。在C
47、DlgDevcode:OnInitDialog()中對(duì)這個(gè)控件(m_list)進(jìn)行初始化(分割列、設(shè)置列寬、設(shè)置風(fēng)格等)。/DlgDevcode.cpp/對(duì)話框的初始化BOOL CDlgDevcode:OnInitDialog() CDialog:OnInitDialog();m_list.InsertColumn(0,"設(shè)備號(hào)");m_list.InsertColumn(1,"設(shè)備名");RECT rect;m_list.GetWindowRect(&rect);int wid = rect.right - rect.left;m_list.S
48、etColumnWidth(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)表格某整行被選中時(shí),將此行的完整數(shù)據(jù)在表格控件的右側(cè)顯示出來(lái)。以后的各個(gè)模塊都用到了這個(gè)方法,這部分的代碼如下:/DlgDevcode.cpp/消息映射部分BEGIN_MESSAGE_MAP(CDlgDevcode, CDial
49、og)/AFX_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(
50、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 = _FILE_;#endif/ CDlgDevcode dialogCDlgDevcode:CDlgDevcode(CWnd* pParent /
51、*=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_DATA_MAP(CDlgDevcode)DDX_Control(pDX, IDC_LIST_DEVC
52、ODE, 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_DCADD, OnBtnDcadd)ON_BN_CLICKED(IDC_BTN_DCDEL, OnBtnD
53、cdel)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 = 0;tryMySet.CreateInstance(_uuidof(Recordset); My
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 勞動(dòng)合同違約責(zé)任及典型案例分析
- 家庭用工合同模板參考范本
- 篇二:購(gòu)房合同范本規(guī)范
- 室內(nèi)防水改造合同范本
- 定制旅行服務(wù)協(xié)議合同
- 房地產(chǎn)開發(fā)施工合同樣本
- 金融市場(chǎng)中銀行承兌質(zhì)押合同的法律效力
- 兼職市場(chǎng)拓展合同樣本
- 發(fā)射設(shè)備在極端環(huán)境下的穩(wěn)定性檢測(cè)考核試卷
- 塑膠跑道材料的生產(chǎn)工藝與質(zhì)量控制考核試卷
- 《智慧旅游認(rèn)知與實(shí)踐》課件-第九章 智慧旅行社
- 馬工程《刑法學(xué)(下冊(cè))》教學(xué)課件 第16章 刑法各論概述
- GPIB控制VP-8194D收音信號(hào)發(fā)生器指令
- 建立良好師生關(guān)系
- 鋼管、扣件、絲杠租賃明細(xì)表
- 施工現(xiàn)場(chǎng)臨電臨水施工方案
- 員工預(yù)支現(xiàn)金與費(fèi)用報(bào)銷流程
- 唐詩(shī)三百首(楷書)
- (新版)公用設(shè)備工程師《專業(yè)知識(shí)》(給排水)考試題庫(kù)及答案
- 01-第一章運(yùn)動(dòng)學(xué)緒論P(yáng)PT課件
評(píng)論
0/150
提交評(píng)論