(精品仓库管理)计算机毕业设计-仓库管理系统
仓库管理系统
仓库管理是整个物资供应管理系统的核心。本实例着重讲解仓库管理模块,给出数据库设计和程序实现过程。
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