当前位置:文档之家› (精品仓库管理)计算机毕业设计-仓库管理系统

(精品仓库管理)计算机毕业设计-仓库管理系统

(精品仓库管理)计算机毕业设计-仓库管理系统
(精品仓库管理)计算机毕业设计-仓库管理系统

(精品仓库管理)计算机毕业设计-仓库管理系统

仓库管理系统

仓库管理是整个物资供应管理系统的核心。本实例着重讲解仓库管理模块,给出数据库设计和程序实现过程。

1、系统设计

1、1系统设计目标

系统开发的总统任务是实现企业物资设备管理的系统化、规范化和自动化,从而达到仓库管理效率的目的。

1、2开发设计思想

在本系统的设计过程中,为了克服仓库管理信息处理量大的困难,满足计算机管理的需要,采取了下面的一些原则:

●●统一各种原始单据的格式,统一帐目和报表的格式。

●●删除不必要的管理冗余,实现管理规范化、科学化。

●●程序代码标准化,软件统一化,确保软件的可维护性和实用性。

●●界面尽量简单化,做到实用、方便,尽量满足企业不同层次员工的需要。

●●建立操作日志,系统自动记录所进行的各种操作。

1、3系统功能分析

本例中的仓库管理系统需要完成的功能主要有以下几点:

●●仓库管理各种信息的输入,包括入库、出库、还库、需求信息的输入等。

●●仓库管理各种信息的查询、修改和维护。

●●设备采购报表的生成。

●●在库存管理中加入最高储备和最低储备字段,对仓库中的物资设备实现监控和报警。

●●企业各部门的物资需求的管理。

●●操作日志的管理。

●●仓库管理系统的使用帮助。

1、4系统功能模块设计

在系统功能分析的基础上,结合VisualC++程序编制的特点,得到如图1-1所示的系统功能模块图。

2

2

图1-8计划采购实体E-R图

图1-9实体和实体之间的关系E-R图

2、3数据库逻辑结构设计

在上面的实体以及实体之间的关系的基础上,形成数据库中的表格和各个表格之间的关系。仓库管理系统数据库中各个表格的设计结果如下面的几个表格所示。每个表格表示在数据库中的一个表。

表1-1设备代码表device_code

列名,数据类型,可否为空,说明

code,VARCHAR2(6),NOTNULL,设备号(主键)

name,VARCHAR2(20),NULL,设备名称

表1-2设备入库表device_in

列名,数据类型,可否为空,说明

code,VARCHAR2(6),NOTNULL,设备号

in_date,DATE,NOTNULL,入库时间(主键)

provider,VARCHAR2(20),NULL,供应商

teleno,VARCHAR2(10),NULL,供应商电话

in_number,NUMBER(6),NULL,入库数量

price,NUMBER(6),NULL,价格

buyer,VARCHAR2(10),NULL,采购员

表1-3设备出库表device_out

列名,数据类型,可否为空,说明

code,VARCHAR2(6),NOTNULL,设备号

department,VARCHAR2(20),NULL,使用部门

out_date,DATE,NULL,出库时间(主键)

out_state,NUMBER(1),NULL,出库状态

out_person,VARCHAR2(10),NULL,经手人

out_number,NUMBER(6),NOTNULL,出库数量

taker,VARCHAR2(10),NULL,领取人

usage,VARCHAR2(20),NULL,用途

表1-4现有库存表device

列名,数据类型,可否为空,说明

code,VARCHAR2(6),NOTNULL,设备号(主键)

now_number,NUMBER(6),NULL,现有库存

high_number,NUMBER(6),NULL,最大库存

low_number,NUMBER(6),NULL,最少库存

total_number,NUMBER(6),NULL,总数

表1-5部门需求表device_need

列名,数据类型,可否为空,说明

code,VARCHAR2(6),NOTNULL,设备号

department,VARCHAR2(20),NOTNULL,部门名称

need_number,NUMBER(6),NULL,需求数量

begin_date,DATE,NULL,需求开始时间

end_date,DATE,NULL,需求结束时间

表1-6设备还库表device_return

列名,数据类型,可否为空,说明

code,VARCHAR2(6),NOTNULL,设备号

return_date,DATE,NULL,还库时间(主键)

keeper,VARCHAR2(20),NULL,仓库管理员

return_number,NUMBER(6),NULL,归还数量

return_date,VARCHAR2(10),NULL,归还人

表1-7操作日志表howdo

列名,数据类型,可否为空,说明

do_user,VARCHAR2(10),NOTNULL,操作员

do_what,VARCHAR2(40),NOTNULL,操作内容

do_date,DATE,NOTNULL,操作时间

表1-8设备采购计划表device_wantbuy

列名,数据类型,可否为空,说明

code,VARCHAR2(6),NOTNULL,设备号

now_number,NUMBER(6),NULL,现有库存

total_number,NUMBER(6),NULL,总库存

max_number,NUMBER(6),NULL,最大库存

buy_number,NUMBER(6),NULL,购买数量

provider,VARCHAR2(10),NULL,供应商

price,NUMBER(6),NULL,价格

buy_date,DATE,NULL,计划采购时间(主键)

3、数据库结构的实现

4、创建应用程序

(1)(1)选择“FileNew”中的“新建项目”选项卡中“MFCAppWizard(exe)”,设置合适的目录和项目名,比如“E:\Project”目录下的“DMS”项目。

(2)(2)创建一个对话框应用程序(“DialogBased”),单击“Next”按钮。

(3)(3)由于在这个项目中将要使用ADO,所以在MFCAppWizard的第二步,需要选中“Automation”选项,使应用程序能够支持自动化对象。如图1-10所示(4)(4)单击“Finish”按钮结束项目的创建。主对话框名为CDMSDlg。

(5)(5)项目创建完毕后,在头文件stdafx.h中加入下面4行:

#import“c:\programfiles\commonfiles\system\ado\msado15.dll”no_namespace(”EOF”,”adoEOF ”)

#include”icrsint.h”

inlinevoidTESTHR(HRESULTx){ifFAILED(x)_com_issue_error(x);};

#defineDATEFMTCstring(“’%s”’)

5、操作日志模块的设计

(1)写日志模块

图1-10使应用程序支持自动化

先定义一个名为ClogMngr的类

//LogMngr.h

//定义一个Log管理器

classCLogMngr

{

public:

CLogMngr();

virtual~CLogMngr();

public:

boolAddLog(LPCSTRop);

voidSetup(_ConnectionPtrcnnt,CString&user)

{

m_DBCnt=cnnt;

m_user=user;

}

protected:

_ConnectionPtrm_DBCnt;

CStringm_user;

};

下面是ClogMngr::AddLog内部实现详细过程。

//LogMngr.cpp

//向数据库中添加Log记录的代码。

boolCLogMngr::AddLog(LPCSTRop)

{

CTimetm=CTime::GetCurrentTime();

CStringsql_;

sql_.Format("INSERTINTOHOWDO(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_tsql=sql_;

try

{

m_DBCnt->Execute(sql,NULL,adCmdText);

}

catch(_com_error&e)

{

CStringError=e.ErrorMessage();

AfxMessageBox(e.ErrorMessage());

returnfalse;

}

returntrue;

}

(2)读日志模块

图1-11查看日志窗口

初始化界面代码如下:

BOOLCDlgViewLog::OnInitDialog()

{

CDialog::OnInitDialog();

m_list.InsertColumn(0,"操作员");

m_list.InsertColumn(1,"操作日期");

m_list.InsertColumn(2,"操作内容");

RECTrect;

m_list.GetWindowRect(&rect);

intwid=rect.right-rect.left;

m_list.SetColumnWidth(0,wid/3);

m_list.SetColumnWidth(1,wid/3);

m_list.SetColumnWidth(2,wid/3);

m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT);

RefreshData();

returnTRUE;//returnTRUEunlessyousetthefocustoacontrol

//EXCEPTION:OCXPropertyPagesshouldreturnFALSE

}

voidCDlgViewLog::RefreshData()

{

m_list.DeleteAllItems();

m_list.SetRedraw(FALSE);

_bstr_tstrSQL("SELECT*FROMHOWDO");

_RecordsetPtrMySet;

inti=0;

try

{

MySet.CreateInstance(__uuidof(Recordset));

MySet=m_DBCnt->Execute(strSQL,NULL,adCmdText);

_variant_tHolder;

while(!MySet->adoEOF)

{

Holder=MySet->GetCollect("do_user");

if(Holder.vt!=VT_NULL)

m_list.InsertItem(i,(char*)(_bstr_t)Holder);

Holder=MySet->GetCollect("do_date");

if(Holder.vt!=VT_NULL)

m_list.SetItemText(i,1,(char*)(_bstr_t)Holder);

Holder=MySet->GetCollect("do_what");

if(Holder.vt!=VT_NULL)

m_list.SetItemText(i,2,(char*)(_bstr_t)Holder);

MySet->MoveNext();

}

MySet->Close();

}

catch(_com_error&e)

{

AfxMessageBox(e.ErrorMessage());

m_list.SetRedraw(TRUE);

return;

}

m_list.SetRedraw(TRUE);

}

voidCDlgViewLog::OnClickListVllog(NMHDR*pNMHDR,LRESULT*pResult) {

inti=m_list.GetSelectionMark();

m_opr=m_list.GetItemText(i,0);

m_date=m_list.GetItemText(i,1);

m_op=m_list.GetItemText(i,2);

UpdateData(FALSE);

*pResult=0;

}

//DlgViewLog.cpp

//删除所有日志记录的函数。

voidCDlgViewLog::OnBtnVlrmall()

{

_bstr_tstrSQL("TRUNCATETABLEHOWDO");

try

{

m_DBCnt->Execute(strSQL,NULL,adCmdText);

}

catch(_com_error&e)

{

AfxMessageBox(e.ErrorMessage());

EndDialog(0);

}

RefreshData();

}

6、登录窗口的设计和程序初始化在CDMSDlg::OnInitDialog()中加入这样一段代码:

//DMSDlg.cpp

//弹出登录界面

CDlgLogIndlg;

do

{

if(!dlg.DoModal())

EndDialog(0);

}while(dlg.m_UsrName.GetLength()==0);

它的目的是弹出图1-12所示的登录对话框,并从中获得一个有效的用户名。

图1-12登录界面

得到有效用户名后,程序用如下代码:

//DMSDlg.cpp

//建立数据库连接,初始化成员变量

//登录数据库,若失败,则关闭程序。

{

m_DBCnt.CreateInstance(__uuidof(Connection));

CStringsql_;

sql_.Format("DSN=DMS;UID=%s;PWD=%s",dlg.m_UsrName,dlg.m_UsrPwd);

_bstr_tsql=sql_;//建立连接

m_DBCnt->Open(sql,"","",-1);//初始化日志管理器

m_logMngr.Setup(m_DBCnt,dlg.m_UsrName);//记录此次登录

m_logMngr.AddLog("登录数据库");

}

catch(_com_error&e)

{

AfxMessageBox(e.ErrorMessage());

this->EndDialog(0);

}

在程序结束时关闭数据库连接。

//DMSDlg.cpp

//关闭数据库连接

voidCDMSDlg::OnDestroy()

{

CDialog::OnDestroy();

m_DBCnt->Close();

}

7、主对话框界面的设计

登录完成后,显示出主对话框。它的界面设计如图1-13所示,单击某个按钮就能弹出某个功能的界面。

图1-13主对话框界面

以其中“设备代码”按钮为例,说明它的事件处理函数。代码如下:

//DMSDlg.cpp

//显示设备代码管理界面

voidCDMSDlg::OnBtnDevcode()

{

CDlgDevcodedlg;

dlg.Setup(m_DBCnt,&m_logMngr);

this->ShowWindow(SW_HIDE);

dlg.DoModal();

this->ShowWindow(SW_SHOW);

}

其他按钮的事件处理函数,代码与“设备代码”按钮的事件处理函数相同。

8、设备代码管理窗口的建立

对话框类名为CdlgDevcode设计如图1-14所示

图1-14设备代码管理窗口

//DlgDevcode.cpp

//对话框的初始化

BOOLCDlgDevcode::OnInitDialog()

{

CDialog::OnInitDialog();//切分列表控件

m_list.InsertColumn(0,"设备号");

m_list.InsertColumn(1,"设备名");

RECTrect;

m_list.GetWindowRect(&rect);

intwid=rect.right-rect.left;

m_list.SetColumnWidth(0,wid/2);

m_list.SetColumnWidth(1,wid/2);

m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT);//读取已有数据

RefreshData();

returnTRUE;

}

//DlgDevcode.cpp

//消息映射部分

BEGIN_MESSAGE_MAP(CDlgDevcode,CDialog)

//{{AFX_MSG_MAP(CDlgDevcode)

ON_NOTIFY(NM_CLICK,IDC_LIST_DEVCODE,OnClickListDevcode)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

//事件处理部分

voidCDlgDevcode::OnClickListDevcode(NMHDR*pNMHDR,LRESULT*pResult)

{

inti=m_list.GetSelectionMark();

m_code=m_list.GetItemText(i,0);

m_name=m_list.GetItemText(i,1);

UpdateData(FALSE);

*pResult=0;

}

其余程序的清单如下:

//DlgDevcode.cpp:implementationfile

//

#include"stdafx.h"

#include"DMS.h"

#include"DlgDevcode.h"

#ifdef_DEBUG

#definenewDEBUG_NEW

#undefTHIS_FILE

staticcharTHIS_FILE[]=__FILE__;

#endif

//////////////////////////////////////////////////////////////////////////// //CDlgDevcodedialog

CDlgDevcode::CDlgDevcode(CWnd*pParent/*=NULL*/)

:CDialog(CDlgDevcode::IDD,pParent)

{

//{{AFX_DATA_INIT(CDlgDevcode)

m_code=_T("");

m_name=_T("");

//}}AFX_DATA_INIT

m_DBCnt=NULL;

m_log=NULL;

}

voidCDlgDevcode::DoDataExchange(CDataExchange*pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_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_MAP

}

BEGIN_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_BN_CLICKED(IDC_BTN_DCUPD,OnBtnDcupd)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

//////////////////////////////////////////////////////////////////////////// //CDlgDevcodemessagehandlers

//负责读取已有数据的函数

voidCDlgDevcode::RefreshData()

{

m_list.DeleteAllItems();

m_list.SetRedraw(FALSE);

_bstr_tstrSQL("SELECT*FROMDEVICE_CODE");

_RecordsetPtrMySet;

inti=0;

try

{

MySet.CreateInstance(__uuidof(Recordset));//执行SOL语句读取记录

MySet=m_DBCnt->Execute(strSQL,NULL,adCmdText);

_variant_tHolder;

while(!MySet->adoEOF)

{//取出code字段的数据

Holder=MySet->GetCollect("code");

if(Holder.vt!=VT_NULL)

m_list.InsertItem(i,(char*)(_bstr_t)Holder);

//取出name字段的数据

Holder=MySet->GetCollect("name");

if(Holder.vt!=VT_NULL)

m_list.SetItemText(i,1,(char*)(_bstr_t)Holder);

MySet->MoveNext();

}

}

catch(_com_error&e)

{

AfxMessageBox(e.ErrorMessage());

m_list.SetRedraw(TRUE);

return;

}

m_list.SetRedraw(TRUE);

}

//负责添加记录的函数

voidCDlgDevcode::OnBtnDcadd()

{

UpdateData();

CStringsql_;

sql_.Format("INSERTINTODEVICE_CODE(code,name)VALUES('%s','%s')",m_code,m_name); _bstr_tsql=sql_;

try

{

m_DBCnt->Execute(sql,NULL,adCmdText);

}

catch(_com_error&e)

{

AfxMessageBox(e.ErrorMessage());

return;

}

m_log->AddLog("添加设备记录。");

RefreshData();

}

//负责删除记录的函数

voidCDlgDevcode::OnBtnDcdel()

{

UpdateData();

CStringsql_;

sql_.Format("DELETEFROMDEVICE_CODEWHERECODE='%s'",m_code);

_bstr_tsql=sql_;

try

{

m_DBCnt->Execute(sql,NULL,adCmdText);

}

catch(_com_error&e)

{

AfxMessageBox(e.ErrorMessage());

return;

}

m_log->AddLog("删除设备记录。");

RefreshData();

}

//负责更新数据的函数

voidCDlgDevcode::OnBtnDcupd()

{

UpdateData();

CStringsql_;

sql_.Format("UPDATEDEVICE_CODESETNAME='%s'WHERECODE='%s'",m_name,m_code);

_bstr_tsql=sql_;

try

{

m_DBCnt->Execute(sql,NULL,adCmdText);

}

catch(_com_error&e)

{

AfxMessageBox(e.ErrorMessage());

return;

}

m_log->AddLog("更新设备记录。");

RefreshData();

}

9、库存信息管理窗口的创建

用户可以在此新增、修改、删除某种设备的记录。单击主对话框中的“库存信息”按钮,将出现图1-15所示的界面。新增记录时,用户在“设备号”组合框中选择一个设备号,在下面填入各种数量,之后单击“新增”按钮即可向表中增加记录。

修改记录时,用户单击列表中某一行,程序利用1、8提到的方法,在窗口下面把这一行记录的详细信息显示出来,用户即可对之修改。

“设备号”这个子窗口初始化的时候有如下代码:

//DlgDev.cpp

//对话框的初始化

BOOLCDlgDev::OnInitDialog()

{

CDialog::OnInitDialog();

//切分列表控件

m_list.InsertColumn(0,"设备号");

m_list.InsertColumn(1,"现存数量");

m_list.InsertColumn(2,"最大数量");

m_list.InsertColumn(3,"最小数量");

m_list.InsertColumn(4,"总数");

RECTrect;

m_list.GetWindowRect(&rect);

intwid=rect.right-rect.left;

m_list.SetColumnWidth(0,wid/5);

m_list.SetColumnWidth(1,wid/5);

m_list.SetColumnWidth(2,wid/5);

m_list.SetColumnWidth(3,wid/5);

m_list.SetColumnWidth(4,wid/5);

m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT);

_RecordsetPtrpRst=NULL;

IADORecordBinding*picRs=NULL;//InterfacePointerdeclared.(VC++Extensions)

CDevCodeRsrs;

try

{

_bstr_tstrSQL("SELECT*FROMDEVICE_CODE");

TESTHR(pRst.CreateInstance(__uuidof(Recordset)));

//读取所有的设备编号

pRst=m_DBCnt->Execute(strSQL,NULL,adCmdText);

//数据绑定

TESTHR(pRst->QueryInterface(__uuidof(IADORecordBinding),(LPVOID*)&picRs));

TESTHR(picRs->BindToRecordset(&rs));

inti=0;

while(!pRst->adoEOF)

{//向组合框控件中添加所有的设备编号

m_devs.AddString(rs.m_sz_code);

pRst->MoveNext();

}

picRs->Release();

pRst->Close();

}

catch(_com_error&e)

{

AfxMessageBox(e.ErrorMessage());

EndDialog(0);

returnTRUE;

}

RefreshData();

returnTRUE;//returnTRUEunlessyousetthefocustoacontrol

//EXCEPTION:OCXPropertyPagesshouldreturnFALSE

}

图1-15库存信息管理

10、设备入库信息管理

在主对话框中单击“入库信息”按钮就进入如图1-16所示的界面。

图1-16设备入库信息管理界面

下面是修改和删除记录的代码:

voidCDlgViewDevIn::OnBtnViupdate()

{

if(!UpdateData())

return;

CStringsql_;

sql_.Format(CString("SELECT*FROMDEVICE_INWHEREin_date=")+DATEFMT,m_date);

_bstr_tsql=sql_;

_RecordsetPtrpRst=NULL;

IADORecordBinding*picRs=NULL;//InterfacePointerdeclared.(VC++Extensions)

CDevInRsrs;

try

{

TESTHR(pRst.CreateInstance(__uuidof(Recordset)));

pRst->Open(sql,_variant_t((IDispatch*)m_DBCnt,true),adOpenKeyset,adLockOptimistic,adCmdTex t);

//数据绑定

TESTHR(pRst->QueryInterface(__uuidof(IADORecordBinding),(LPVOID*)&picRs));

TESTHR(picRs->BindToRecordset(&rs));

//填写需要修改的数据

strcpy(rs.m_sz_code,m_code);

strcpy(rs.m_sz_date,m_date);

strcpy(rs.m_sz_provider,m_provider);

strcpy(rs.m_sz_tel,m_tel);

rs.m_f_number=m_number;

rs.m_f_price=m_price;

strcpy(rs.m_sz_buyer,m_buyer);

//开始更新数据

TESTHR(picRs->Update(&rs));

//释放ADO对象

picRs->Release();

pRst->Close();

}

catch(_com_error&e)

{

AfxMessageBox(e.ErrorMessage());

return;

}

MessageBox("完成操作!");

m_log->AddLog("修改入库信息");

RefreshData();

}

voidCDlgViewDevIn::OnBtnVidel()

{

if(!UpdateData())

return;

CStringsql_;

sql_.Format(CString("DELETEFROMDEVICE_INWHEREin_date=")+DATEFMT,m_date);

_bstr_tsql=sql_;

try

{//执行删除数据的SOL语句

m_DBCnt->Execute(sql,NULL,adCmdText);

}

catch(_com_error&e)

{

AfxMessageBox(e.ErrorMessage());

return;

}

MessageBox("完成操作!");

m_log->AddLog("删除入库信息");

RefreshData();

}

11、设备入库窗口

在主对话框中单击“设备入库”按钮就进入如图1-17所示的界面。

图1-17设备入库登记界面

下面就是单击“确定”按钮之后,更新数据库操作的代码:

//DlgDevIn.cpp

//添加入库记录

voidCDlgDevIn::OnBtnDiadd()

{

if(m_devs.GetCurSel()==CB_ERR)

{

MessageBox("请选择一个设备");

return;

}

if(!UpdateData())

return;

_RecordsetPtrpRst=NULL;

CDevInRsrs;

try

{

TESTHR(pRst.CreateInstance(__uuidof(Recordset)));

//打开数据库表格到Recordest对象

pRst->Open("device_in",_variant_t((IDispatch*)m_DBCnt,true),adOpenKeyset,adLockOptimistic, adCmdTable);

//填写新数据

m_devs.GetWindowText(rs.m_sz_code,11);

sprintf(rs.m_sz_date,"%d-%d-%d%d:%d:%d",

m_date.GetYear(),m_date.GetMonth(),m_date.GetDay(),

m_time.GetHour(),m_time.GetMinute(),m_time.GetSecond());

strcpy(rs.m_sz_provider,m_provider);

strcpy(rs.m_sz_tel,m_tel);

rs.m_f_number=m_number;

rs.m_f_price=m_price;

strcpy(rs.m_sz_buyer,m_buyer);

COleSafeArrayvaFieldlist,vaValuelist;

rs.FillFieldsArray(vaFieldlist,vaValuelist);

//开始一个事务

m_DBCnt->BeginTrans();

//添加新数据到device_in表

TESTHR(pRst->AddNew(vaFieldlist,vaValuelist));

pRst->Close();

//打开device表

CStringsql_;

sql_.Format("SELECT*FROMdeviceWHEREcode='%s'",rs.m_sz_code);

_bstr_tsql=sql_;

pRst->Open(sql,_variant_t((IDispatch*)m_DBCnt,true),adOpenKeyset,adLockOptimistic,adCmdTex t);

//若没有此设备的库存记录

if(pRst->GetRecordCount()==0)

{

CDevRsrsDev;

strcpy(rsDev.m_sz_code,rs.m_sz_code);

rsDev.m_f_cur=rs.m_f_number;

rsDev.m_f_total=rs.m_f_number;

rsDev.m_f_max=1;

rsDev.m_f_min=1;

//创建一个设备库存记录

COleSafeArrayvaFields,vaValues;

rsDev.FillFieldsArray(vaFields,vaValues);

TESTHR(pRst->AddNew(vaFields,vaValues));

}else//若有此设备的库存记录

{

CDevRsrsDev;

IADORecordBinding*picRs=NULL;//InterfacePointerdeclared.(VC++Extensions)

TESTHR(pRst->QueryInterface(__uuidof(IADORecordBinding),(LPVOID*)&picRs));

TESTHR(picRs->BindToRecordset(&rsDev));

strcpy(rsDev.m_sz_code,rs.m_sz_code);

rsDev.m_f_cur=rs.m_f_number+rsDev.m_f_cur;

rsDev.m_f_total=rs.m_f_number+rsDev.m_f_total;

//修改原有的设备库存记录

TESTHR(picRs->Update(&rsDev));

picRs->Release();

}

pRst->Close();

//提交事务

m_DBCnt->CommitTrans();

}

catch(_com_error&e)

{

AfxMessageBox(e.ErrorMessage());

m_DBCnt->RollbackTrans();

return;

}

MessageBox("完成操作!");

m_log->AddLog("添加入库信息");

EndDialog(0);

}

12、设备采购报表的管理

在主对话框中单击“生成设备采购计划报表”按钮就进入如图1-18所示的界面。

此时程序自动显示设备的名称、总库存、最大库存、现有库存等信息,待用户输入完其他数据之后,将生成一个设备采购计划报表,存入数据库中。

图1-18设备采购计划报表界面

//DlgReport.cpp

//显示所选中设备的信息

voidCDlgReport::OnCloseupComboRpdevs()

{

charbuf[64];

//读取用户所选的编号

m_devs.GetWindowText(buf,64);

if(strlen(buf)<=0)

return;

_RecordsetPtrpRst=NULL;

IADORecordBinding*picRs=NULL;//InterfacePointerdeclared.(VC++Extensions)

CDevCodeRsrs1;

CDevRsrs2;

_bstr_tstrSQL;

try

{生成所需的SQL语句

CStringsql;

sql.Format("SELECT*FROMDEVICE_CODEWHEREcode='%s'",buf);

strSQL=sql;

TESTHR(pRst.CreateInstance(__uuidof(Recordset)));

pRst=m_DBCnt->Execute(strSQL,NULL,adCmdText);

//读取编号对应的设备名称

TESTHR(pRst->QueryInterface(__uuidof(IADORecordBinding),(LPVOID*)&picRs));

TESTHR(picRs->BindToRecordset(&rs1));

m_name.Format("%s",rs1.m_sz_name);

结束操作

picRs->Release();

pRst->Close();

}

catch(_com_error&e)

{

AfxMessageBox(e.ErrorMessage());

}

try

{

CStringsql;

sql.Format("SELECT*FROMDEVICEWHEREcode='%s'",buf);

strSQL=sql;

TESTHR(pRst.CreateInstance(__uuidof(Recordset)));

pRst->Open(strSQL,_variant_t((IDispatch*)m_DBCnt,true),adOpenKeyset, adLockOptimistic,adCmdText);

if(pRst->GetRecordCount()!=1)

{

m_max=0;

m_cur=0;

m_total=0;

}else

{

TESTHR(pRst->QueryInterface(__uuidof(IADORecordBinding),(LPVOID*)&picRs)); TESTHR(picRs->BindToRecordset(&rs2));

//读取编号对应的库存情况

m_max=rs2.m_f_max;

m_cur=rs2.m_f_cur;

m_total=rs2.m_f_total;

picRs->Release();

}

pRst->Close();

}

catch(_com_error&e)

{

AfxMessageBox(e.ErrorMessage());

}

UpdateData(FALSE);

}

13、库存报警窗口

在主对话框中单击“库存报警”按钮就进入如图1-19所示的界面。

图1-19库存报警界面

检索记录的代码如下:

//DlgDevAlert.cpp

//检索过多、过少库存

voidCDlgDevAlert::SearchOver()

{

_RecordsetPtrpRst=NULL;

IADORecordBinding*picRs=NULL;//InterfacePointerdeclared.(VC++Extensions)

CDevRsrs;

try

{

_bstr_tstrSQL("SELECT*FROMDEVICEWHEREnow_number>high_number");

TESTHR(pRst.CreateInstance(__uuidof(Recordset)));

pRst=m_DBCnt->Execute(strSQL,NULL,adCmdText);

TESTHR(pRst->QueryInterface(__uuidof(IADORecordBinding),(LPVOID*)&picRs));

TESTHR(picRs->BindToRecordset(&rs));

inti=0;

charbuf[64];

while(!pRst->adoEOF)

{

m_list.InsertItem(0,rs.m_sz_code);

sprintf(buf,"%f",rs.m_f_cur);m_list.SetItemText(i,1,buf);

sprintf(buf,"%f",rs.m_f_max);m_list.SetItemText(i,2,buf);

sprintf(buf,"%f",rs.m_f_min);m_list.SetItemText(i,3,buf);

sprintf(buf,"%f",rs.m_f_total);m_list.SetItemText(i,4,buf);

pRst->MoveNext();

}

picRs->Release();

pRst->Close();

}

catch(_com_error&e)

{

AfxMessageBox(e.ErrorMessage());

return;

}

}

voidCDlgDevAlert::SearchBelow()

{

_RecordsetPtrpRst=NULL;

IADORecordBinding*picRs=NULL;//InterfacePointerdeclared.(VC++Extensions)

CDevRsrs;

try

{

_bstr_tstrSQL("SELECT*FROMDEVICEWHEREnow_number

TESTHR(pRst.CreateInstance(__uuidof(Recordset)));

pRst=m_DBCnt->Execute(strSQL,NULL,adCmdText);

TESTHR(pRst->QueryInterface(__uuidof(IADORecordBinding),(LPVOID*)&picRs));

TESTHR(picRs->BindToRecordset(&rs));

inti=0;

charbuf[64];

while(!pRst->adoEOF)

{

m_list.InsertItem(0,rs.m_sz_code);

sprintf(buf,"%f",rs.m_f_cur);m_list.SetItemText(i,1,buf);

sprintf(buf,"%f",rs.m_f_max);m_list.SetItemText(i,2,buf);

sprintf(buf,"%f",rs.m_f_min);m_list.SetItemText(i,3,buf);

sprintf(buf,"%f",rs.m_f_total);m_list.SetItemText(i,4,buf);

pRst->MoveNext();

}

picRs->Release();

pRst->Close();

}

catch(_com_error&e)

{

AfxMessageBox(e.ErrorMessage());

return;

}

}

14、帮助模块设计

本系统的帮助模块由两部分组成,一部分是本程序的About窗口,另一个是在外部编译好的chm格式的帮助文件。单击主对话框中的相应按钮可以分别激活这两部分功能。

下面是“帮助”和“关于”两个按钮的消息处理函数:

//DMSDlg.cpp

//激活“帮助”和“关于”

voidCDMSDlg::OnBtnAbout()

{

CAboutDlgdlg;

dlg.DoModal();

}

voidCDMSDlg::OnBtnHelp()

{

WinExec("hh.exedms.chm",SW_SHOW);

}

第二个函数调用WinExec这个Win32API激活了外部的chm帮助文件

图1-20是“关于”窗口的界面

图1-20“关于”窗口的界面

15、小结

在运行程序之前,请将所附的数据库文件dms.mdb添加为数据源,并命名为DMS。密码为:111

相关主题
文本预览
相关文档 最新文档