需求分析:
设计药品进销存系统并分为六个功能模块。主要用来管理一个小型的药品销售公司。主要有药品的入库、出库,供货商的管理,客户管理以及必要的库存检索。系统用orcal管理数据库,通过MFC实现软件界面可视化,通过函数连接数据库,实现对数据库的基本操作,下面具体分析每个功能模块:
药品清单:
可以建立一张表用于存放药品相关信息。药品的相关信息包括:货号、药品名称、类型、进价、售价、生产日期以及有效期至。可以添加一条记录到药品清单中,也可以删除一条记录,也可以显示药品清单中所有的记录项,实现对这张表的简单管理。
供货商清单:
可以建立一张表存放供货商的相关信息。供货商清单的相关数据项包括:供货商号、供货商名称、供货商地点、联系电话。可以添加一条记录到供货商清单表中,也可以删除掉一条记录,也可以显示供货商清单中的所有记录,实现对供货商信息的简单管理。
客户清单:
可以建立一张表存放客户的相关信息。客户清单的相关数据项包括:客户编号、客户名称、地点、电话。可以添加一条记录到客户清单表中,也可以删除掉一条记录,也可以显示客户清单中的所有记录,实现对客户信息的简单管理。
进货单:
当有药品入库时,进货单中要增加一条相关记录,以记录药品入库信息。进货单包括的数据项有:编号、供货商号、货号、仓库、进货数量以及进货日期,进货单中可以增加上一条记录,但是不可以删除一条记录,可以显示进货单中的所有记录,实现对进货单的相关管理。
售货单:
当有药品出库时,售货单中要增加一条相关记录,以记录药品出库信息。售货单包括的数据项有:编号、客户编号、货号、仓库、销售数量以及销售日期,售货单中可以增加上一条记录,但是不可以删除一条记录,可以显示售货单中的所有记录,实现对售货单的相关管理。
库存库:
当有药品入库时,库存库要增加相关记录或修改相关记录,当有药品出库时,库存库要修改相关记录或当出库不成功时给出相关警告信息。库存库包括以下数据项:货号、仓库、库存数量、库存单价、库存金额。
概念结构设计:
实体间E_R图
关系模型:(带下划线的表示表的主键)
药品清单(货号,药品名称,类型,进价,售价,生产日期,有效期至)
供货商清单(供货商号,供货商名称,供货商地点,联系电话)
客户清单(客户编码,客户简称,地址,电话)
进货单(编号,供货商号,货号,仓库,进货数量,进货日期)
售货单(编号,客户编号,货号,仓库,销售数量,销售日期)
库存库(货号,仓库,库存数量,库存单价,库存金额)
建表:
增加药品清单表
create table 药品清单
(
货号 varchar(15),
药品名称 varchar(20),
类型 varchar(6),
进价 number(3,1),
售价 number(3,1),
生产日期 date,
有效期至 date,
constraint PK_药品清单 primary key (货号)
);
增加供货商清单表
create table 供货商清单
(
供货商号 varchar(15),
供货商名称 varchar(20),
供货商地点 varchar(20),
联系电话 varchar(15),
constraint PK_供货商清单 primary key(供货商号)
);
增加客户清单表
create table 客户清单
(
客户编码 varchar(15),
客户简称 varchar(15),
地址 varchar(15),
电话 varchar(15),
constraint PK_客户清单 PRIMARY KEY (客户编码)
);
增加进货单表
create table 进货单
(
编号 varchar(15),
供货商号 varchar(20),
货号 varchar(20),
仓库 varchar(10),
进货数量 number(5),check(进货数量>=0),
进货日期 date,
constraint PK_进货单 PRIMARY KEY (编号),
constraint FK_进货单_To_药品清单 FOREIGN KEY (货号)
REFERENCES 药品清单(货号),
constraint FK_进货单_To_供销商清单 FOREIGN KEY (供货商号)
REFERENCES 供货商清单(供货商号)
);
增加售货单表
create table 售货单
(
编号 varchar(15),
客户编号 varchar(20),
货号 varchar(15),
仓库 varchar(10),
销售数量 number(5),
销售日期 date,
constraint PK_售货单 primary key (编号),
constraint FK_售货单_To_药品清单 FOREIGN KEY (货号)
REFERENCES 药品清单(货号),
constraint FK_售货单_To_客户清单 FOREIGN KEY (客户编号)
REFERENCES 客户清单(客户编码)
);
增加库存库
create table 库存库
(
货号 varchar(15),
仓库 varchar(15),
库存数量 number(5),
库存单价 number(3,1),
库存金额 number(7)
);
数据库实施与维护:
整个系统的操作过程:
首先进入登陆界面,用户名和密码都为空,直接单击确认即进入操作界面,单击六个模块中的任意一个按钮进入与其有关的操作界面,再选择所要进行的操作即可弹出相关的对话框,输入用户名和密码后就可实现一系列功能如增加记录,删除和显示记录。在操作失误的时候系统会给出相应的提示和警告,以提示用户输入规范的数据和进行当前可以进行的操作。系统优点就是实现了操作并运行成功了,缺点是没有一个人性化的操作界面,操作也让人感到困倦,总的原因还是道行不深,不愿花费太大的精力,属于注重实现,忽略细节的类型。
MFC的代码实现部分:
登陆界面实现代码
void CMedicineProjectView::OnButton1()
{
// TODO: Add your control notification handler code here
CZhuyemian zhuyemian;
CADMINSET adminset;
CString yonghuming;
CString mima;
UpdateData(TRUE);
//CCzhuyemian dlg;
adminset.Open();
GetDlgItem(IDC_EDIT1)->GetWindowText(yonghuming);
GetDlgItem(IDC_EDIT2)->GetWindowText(mima);
if(adminset.m_SA_NAME!=yonghuming||adminset.m_SA_VALUE!=mima)
MessageBox("用户名或密码错误!");
else
zhuyemian.DoModal();
//zhuyemian.EndDialog(IDD_MEDICINEPROJECT_FORM);
//EndDialog(GetSafeHwnd( ),IDD_MEDICINEPROJECT_FORM);
}
主界面操作代码
void CZhuyemian::OnButton2()
{
// TODO: Add your control notification handler code here
CClientZhujiemian clientzhujiemian;
clientzhujiemian.DoModal();
}
void CZhuyemian::OnButton3()
{
// TODO: Add your control notification handler code here
CProviderzhujiemian providerzhujiemian;
providerzhujiemian.DoModal();
}
void CZhuyemian::OnButton1()
{
// TODO: Add your control notification handler code here
CMedicinezhujiemian medicinezhujiemian;
medicinezhujiemian.DoModal();
}
void CZhuyemian::OnButton5()
{
// TODO: Add your control notification handler code here
CInlistzhujiemian inlistzhujiemian;
inlistzhujiemian.DoModal();
}
void CZhuyemian::OnButton4()
{
// TODO: Add your control notification handler code here
COutlistzhujiemian outlistzhujiemian;
outlistzhujiemian.DoModal();
}
void CZhuyemian::OnButton6()
{
// TODO: Add your control notification handler code here
CKucunkuzhujiemian kucunkuzhujiemian;
kucunkuzhujiemian.DoModal();
}
客户操作的实现代码(药品清单、供货商操作代码类似,在此省略)
// ClientZhujiemian.cpp : implementation file
//
#include "stdafx.h"
#include "MedicineProject.h"
#include "ClientZhujiemian.h"
#include "Clientitems.h"
#include "ClientSet.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CClientZhujiemian dialog
CClientZhujiemian::CClientZhujiemian(CWnd* pParent /*=NULL*/)
: CDialog(CClientZhujiemian::IDD, pParent)
{
//{{AFX_DATA_INIT(CClientZhujiemian)
//}}AFX_DATA_INIT
}
void CClientZhujiemian::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CClientZhujiemian)
DDX_Control(pDX, IDC_LIST1, m_Listbox);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CClientZhujiemian, CDialog)
//{{AFX_MSG_MAP(CClientZhujiemian)
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
ON_BN_CLICKED(IDC_BUTTON3, OnButton3)
ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CClientZhujiemian message handlers
void CClientZhujiemian::OnButton1()
{
// TODO: Add your control notification handler code here
CClientitems clientitems;
clientitems.DoModal();
}
void CClientZhujiemian::OnButton3()
{
// TODO: Add your control notification handler code here
m_Listbox.Invalidate(FALSE);
int n=m_Listbox.GetCount();
while(n>=0){
m_Listbox.DeleteString(n);
n--;
}
UpdateData(FALSE);
CClientSet clientshow;
m_Listbox.SetHorizontalExtent(100);
clientshow.Open();
clientshow.MoveFirst();
while(!clientshow.IsEOF()){
m_Listbox.AddString(clientshow.m_column1+" "+clientshow.m_column2+" "+
clientshow.m_column3+" "+clientshow.m_column4);
clientshow.MoveNext();
}
clientshow.MoveFirst();
clientshow.Close();
UpdateData(TRUE);
m_Listbox.Invalidate(FALSE);
}
void CClientZhujiemian::OnButton2()
{
// TODO: Add your control notification handler code here
CClientSet clientdelete;
int n;
n=m_Listbox.GetCurSel()+1;
char s[10];
itoa(n,s,10);
MessageBox(s);
clientdelete.Open();
clientdelete.MoveFirst();
if(n==1)
clientdelete.Delete();
else{
while(n>1)
{
clientdelete.MoveNext();
n=n-1;}
clientdelete.Delete();
}
clientdelete.Close();
}
进货单操作界面代码(售货单操作界面代码类似,省略)
void CInlistzhujiemian::OnButton1()
{
// TODO: Add your control notification handler code here
CInlistitems inlistitems;
inlistitems.DoModal();
}
void CInlistzhujiemian::OnButton3()
{
// TODO: Add your control notification handler code here
m_listbox.Invalidate(FALSE);
int n=m_listbox.GetCount();
while(n>=0){
m_listbox.DeleteString(n);
n--;
}
UpdateData(FALSE);
CInlistSet1 inlistshow;
CString a,b;
inlistshow.Open();
inlistshow.MoveFirst();
m_listbox.SetHorizontalExtent(100);
while(!inlistshow.IsEOF()){
a=(CString)inlistshow.m_column5;
b=inlistshow.m_column6.Format("%A %B %d %Y");
m_listbox.AddString(inlistshow.m_column1+" "+inlistshow.m_column2+" "+
inlistshow.m_column3+" "+inlistshow.m_column4+" "+a+" "+b);
inlistshow.MoveNext();
}
inlistshow.MoveFirst();
inlistshow.Close();
UpdateData(TRUE);
m_listbox.Invalidate(FALSE);
}
增加进货单相关信息代码
void CInlistitems::OnButton1()
{
// TODO: Add your control notification handler code here
CInlistSet1 addrecordset;//定义进货单和库存库对象
CKucunkuset3 addtokucunkuset;
CString a,b,c,d;
CString e;
addrecordset.Open();
addtokucunkuset.Open();
e=(CString)m_inlistshuliang;
if(addrecordset.GetRecordCount())
addrecordset.MoveLast();
GetDlgItem(IDC_EDIT1)->GetWindowText(a);//CString类型的变量a得到IDC_EDIT1控件中的内容
GetDlgItem(IDC_EDIT2)->GetWindowText(b);
GetDlgItem(IDC_EDIT3)->GetWindowText(c);
GetDlgItem(IDC_EDIT4)->GetWindowText(d);
GetDlgItem(IDC_EDIT5)->GetWindowText(e);
if(a.IsEmpty()||b.IsEmpty()||c.IsEmpty()||d.IsEmpty())
{
MessageBox("信息不能为空!");
}
else
{
addrecordset.AddNew();//和售货单不同,只要进货就要往库存库中做记录,而且库存库记录依赖于
addrecordset.m_column1=a;//进货单相应记录的不同变化而出现不同情况,所以先插入进货单,再
addrecordset.m_column2=b;//插入或变更库存库的记录
addrecordset.m_column3=c;
addrecordset.m_column4=d;
addrecordset.m_column5=e;
addrecordset.m_column6=m_inlistdate;
int n=0;//(n的值为什么一直是一呢,不,是反复无常啊!)用n来得到库存库中的记录个数
char nn[2];
if(addtokucunkuset.GetRecordCount()){
addtokucunkuset.MoveFirst();
while(!addtokucunkuset.IsEOF()){
addtokucunkuset.MoveNext();
n++;}
n++;
}
itoa(n,nn,10);
MessageBox(nn);//验证n的大小
/*int n;//这种情况下n总是一
char nn[2];
n=addtokucunkuset.GetRecordCount();
itoa(n,nn,10);
MessageBox(nn);*/
if(n>1)
addtokucunkuset.MoveFirst();
while(n>0){
if(addtokucunkuset.m_column1==c&&addtokucunkuset.m_column2==d)
break;
else{
if(addtokucunkuset.IsEOF())
{n--;
break;}
else{
addtokucunkuset.MoveNext();
n--;}
}
}
if(n)//如果有相应的记录,做更改操作
{
float price,sum,sum0;
int number,number0;
CString summ;
CString jiage;
CString numberr;
CMedicineSet medicineset;
medicineset.Open();
medicineset.MoveFirst();
while(medicineset.m_column1!=c)
medicineset.MoveNext();
price=atof(medicineset.m_column4);
number=atoi(e);
number0=atoi(addtokucunkuset.m_column3);
number0=number0+number;
sum=price*number;
sum0=atof(addtokucunkuset.m_column5);
sum0=sum0+sum;
summ.Format("%f",sum0);
numberr.Format("%d",number0);
jiage.Format("%f",sum0/number0);
MessageBox(summ);
addtokucunkuset.Edit();
addtokucunkuset.m_column3=numberr;
addtokucunkuset.m_column5=summ;
addtokucunkuset.m_column4=jiage;
medicineset.Close();
GetDlgItem(IDC_EDIT1)->SetWindowText("");//把对话框上的几个edit控件中的内容置"即清空
GetDlgItem(IDC_EDIT2)->SetWindowText("");
GetDlgItem(IDC_EDIT3)->SetWindowText("");
GetDlgItem(IDC_EDIT4)->SetWindowText("");
GetDlgItem(IDC_EDIT5)->SetWindowText("");
addtokucunkuset.Update();
addrecordset.Update();
addtokucunkuset.Close();
addrecordset.Close();
return;
}
if(n==0)//如果库存库中没有与输入记录相关的记录,做插入操作
{
float price,sum;
int number;
CString summm;
CMedicineSet medicineset;
medicineset.Open();
medicineset.MoveFirst();
while(medicineset.m_column1!=c)
medicineset.MoveNext();
addtokucunkuset.AddNew();
price=atof(medicineset.m_column4);
number=atoi(e);
sum=price*number;
summm.Format("%f",sum);
addtokucunkuset.m_column1=c;
addtokucunkuset.m_column2=d;
addtokucunkuset.m_column3=e;
addtokucunkuset.m_column4=medicineset.m_column4;
addtokucunkuset.m_column5=summm;
medicineset.Close();
GetDlgItem(IDC_EDIT1)->SetWindowText("");//把对话框上的几个edit控件中的内容置"即清空
GetDlgItem(IDC_EDIT2)->SetWindowText("");
GetDlgItem(IDC_EDIT3)->SetWindowText("");
GetDlgItem(IDC_EDIT4)->SetWindowText("");
GetDlgItem(IDC_EDIT5)->SetWindowText("");
addtokucunkuset.Update();
addrecordset.Update();
addtokucunkuset.Close();
addrecordset.Close();
return;
}
}
}
库存库操作代码
void CKucunkuzhujiemian::OnButton1()
{
// TODO: Add your control notification handler code here
m_listbox.Invalidate(FALSE);
int n=m_listbox.GetCount();
while(n>=0){
m_listbox.DeleteString(n);
n--;
}
UpdateData(FALSE);
CKucunkuset3 kucunkushow;
CString a,b;
kucunkushow.Open();
kucunkushow.MoveFirst();
char xx[6];
int x=kucunkushow.GetRecordCount();
itoa(x,xx,10);
MessageBox(xx);
m_listbox.SetHorizontalExtent(100);
while(!kucunkushow.IsEOF()){
m_listbox.AddString(kucunkushow.m_column1+" "+kucunkushow.m_column2+" "+
kucunkushow.m_column3+" "+kucunkushow.m_column4+" "+kucunkushow.m_column5);
kucunkushow.MoveNext();
}
kucunkushow.MoveFirst();
kucunkushow.Close();
UpdateData(TRUE);
m_listbox.Invalidate(FALSE);
}
具体操作相关截图:
登陆界面:
具体的某一操作界面:
总结:
优点寥寥无几,缺点不少,总体感觉还算满足,让我做一个太好的项目也不太可能,而自己也知道项目本身也有很大的改进余地,总的感觉是在编程的过程中还是了解了一些应该了解的知识,也能够在最后运行成功,这也算达到了本来心目中就不辉煌的目标,程序本身能实现简单的插入删除和检索功能,能够实现多个表之间数据交换时应该处理的操作,也深刻的了解到了编程在某种意义上的不易和容易,真正去做是很重要的,同学之间的相互商讨也是必要的,要真正实现一个漂亮的程序是不容易的,当然这也是一个熟练的程度,有兴趣的人可以编写出比较花哨的界面效果和实现步骤,当然这也是个人的兴趣问题。