三 概要设计
3.1 E—R图和相关说明
类别(类别编号,类别名称,上级类别)
仓库(仓库编号,隶属单位,备注)
用户(用户名,密码,权限类型);
客户(客户编号,联系人,单位,联系电话,传真,通信地址,邮政编码)

产品(编号,名称,规格,计算单位,参考价格,数量下限,数量下限,有效期,警告
出库(出库类型,产品类型,单价,数量,总价格,客户单位,出库仓库,经办用户,出库日期)
入库(入库类型,产品名称,生产日期,单价,数量,总价格,客户单位,入库仓库,经办用户,入库日期)
库存(产品入库单价,库存数量,生产日期)
四 逻辑设计
(一)、表的定义如下 :
Client表(客户信息表) Product(产品信息表)
ProinStore(库存信息表) Takeout(出库表)
StoreIn(入库表) Users(用户表)
ProType(产品类型表) Storehouse(仓库信息表)
(二)、视图定义如下:
一、report2(报表视图)
CREATE VIEW Report2
AS
SELECT SiType, Pid, Pprice, Pnum, (Pprice * Pnum) As Amount,
Cid, Sid, EmpName, OptDate FROM StoreIn
UNION
SELECT Ttype, Pid, Pprice, Pnum, (Pprice * Pnum) As Amount, Cid, Sid, EmpName, OptDate FROM TakeOut
二、 库存统计视图
CREATE VIEW Total_Num
AS
SELECT dbo.ProInStore.Pid, SUM(dbo.ProInStore.Pnum) AS Total
FROM dbo.ProInStore INNER JOIN
dbo.Product ON dbo.ProInStore.Pid = dbo.Product.Pid
GROUP BY dbo.ProInStore.Pid
三、库存视图
CREATE VIEW dbo.v_ProInStore
AS
SELECT p.Pid, SUM(s.Pnum) AS SumNum
FROM dbo.Product p INNER JOIN
dbo.ProInStore s ON p.Pid = s.Pid
GROUP BY p.Pid
四、入库视图
CREATE VIEW dbo.v_storein
AS
SELECT p.Pid, SUM(i.Pnum) AS SumNum, SUM(i.Pnum * i.Pprice)
AS SumPrice
FROM dbo.Product p INNER JOIN
dbo.StoreIn i ON p.Pid = i.Pid
GROUP BY p.Pid
五、出库视图
CREATE VIEW dbo.v_takeout
AS
SELECT p.Pid, SUM(t.Pnum) AS SumNum, SUM(t.Pnum * t.Pprice)
AS SumPrice
FROM dbo.Product p INNER JOIN
dbo.TakeOut t ON p.Pid = t.Pid
GROUP BY p.Pid
六、失效期统计视图
CREATE VIEW dbo.Valid
AS
SELECT dbo.ProInStore.SpId AS 库存记录编号, dbo.Product.Pname AS 产品名称,
dbo.ProInStore.Pprice AS 产品价格, dbo.ProInStore.Pnum AS 产品数量,
dbo.ProInStore.MakeDate AS 生产日期, dbo.Storehouse.Sname AS 仓库名称,
ROUND(DATEDIFF(day, DATEADD(day, dbo.Product.Valid, dbo.ProInStore.MakeDate),
GETDATE()), 0) AS 距离失效期的天数
FROM dbo.ProInStore INNER JOIN
dbo.Product ON dbo.ProInStore.Pid = dbo.Product.Pid AND DATEDIFF(day,
GETDATE(), dbo.ProInStore.MakeDate)
>= dbo.Product.Valid - dbo.Product.AlarmDays INNER JOIN
dbo.Storehouse ON dbo.ProInStore.Sid = dbo.Storehouse.Sid
五 详细设计
总体模块设计如下:
模块一(基本信息管理)(由本人完成)
准备工作:
一完成对数据库连接和操作的类
#import "c:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","adoEOF") rename("BOF","adoBOF")
class ADOConn
{// 定义变量
public:
_ConnectionPtr m_pConnection; //添加一个指向Connection对象的指针:
_RecordsetPtr m_pRecordset; //添加一个指向Recordset对象的指针:
public: // 定义方法
ADOConn();
virtual ~ADOConn(); // 初始化—连接数据库
void OnInitADOConn();
_RecordsetPtr& GetRecordSet(_bstr_t bstrSQL); // 执行查询
BOOL ExecuteSQL(_bstr_t bstrSQL); // 执行SQL语句,Insert Update _variant_t
void ExitConnect();
void Backup(); //备份数据库
void Restore();//恢复数据库};
一、用户登陆:
实现代码如下:
class CLoginDlg : public CDialog
{
// Construction
public:
CLoginDlg(CWnd* pParent = NULL); // standard constructor
~CLoginDlg();
// Dialog Data
//{{AFX_DATA(CLoginDlg)
enum { IDD = IDD_LOGIN_DIALOG };
CEdit m_control_username;
CEdit m_control_password;
int count;
int seconds;
CSMButton m_ok;
CSMButton m_cancel;
CString m_Pwd;
CString m_UserName;
COLORREF m_clrText;
COLORREF m_clrBkgnd;
CBrush m_brBkgnd;
CBrush m_brControlBkgnd1;
CBrush m_brControlBkgnd2;
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual void OnOK();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg void OnTimer(UINT nIDEvent);
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
void CLoginDlg::OnOK()
{UpdateData(TRUE);
if (m_UserName == ""){
MessageBox("请输入用户名");
return;}
if (m_Pwd == ""){
MessageBox("请输入密码");
return;}
//定义CUsers对象,用于从表Users中读取数据
CUsers user;
user.GetData(m_UserName);
//如果读取的数据与用户输入数据不同,则返回
if (user.GetPwd() != m_Pwd)
{ if (count<3)
{MessageBox("用户信息不正确,无法登录!");
count++;
m_Pwd.Empty();
m_control_password.SetFocus();
UpdateData(FALSE);}
else
{
MessageBox("你可能是非法用户!","警告",MB_OK|MB_ICONHAND);
exit(0); }}else{KillTimer(0);CDialog::OnOK();}}
二、客户的实现代码
void CClientManDlg::Refresh_Data()
{
UpdateData(TRUE); //将控件的值读取到成员变量中
CString cSource;
CString cCtype; //读取客户类型值
cCtype.Format("%d", m_Ctype.GetCurSel() + 1);
//设置SELECT语句,按客户单位排序
cSource = "SELECT Cid, Cname AS 客户单位, Contact AS 联系人, Address AS 通信地址,";
cSource += " Postcode AS 邮政编码, Phone AS 联系电话, Fax AS 传真电话, Memo AS 备注";
cSource += " FROM Client WHERE Ctype=" + cCtype + " ORDER BY Cname";
m_adodc.SetRecordSource(cSource);
m_adodc.Refresh();
//设置表格列宽度
_variant_t vIndex;
vIndex = long(0);
m_datagrid.GetColumns().GetItem(vIndex).SetWidth(0);
}
BOOL CClientManDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
m_Ctype.SetCurSel(0); //设置客户类型
Refresh_Data(); //刷新表格中的记录集
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CClientManDlg::OnAddButton()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
//打开编辑对话框
CClientEditDlg dlg;
dlg.cCid = "";
dlg.iCtype = m_Ctype.GetCurSel() + 1;
if (dlg.DoModal() == IDOK)
Refresh_Data();
}
void CClientManDlg::OnSelchangeCtypeCombo()
{
// TODO: Add your control notification handler code here
Refresh_Data();
}
void CClientManDlg::OnModiButton()
{
// TODO: Add your control notification handler code here
if (m_adodc.GetRecordset().GetEof())
{
MessageBox("请选择要修改的记录");
return;
}
UpdateData(TRUE);
CClientEditDlg dlg;
dlg.cCid = m_datagrid.GetItem(0); //记录编号
dlg.iCtype = m_Ctype.GetCurSel() + 1; //客户类型
dlg.m_Cname = m_datagrid.GetItem(1); //单位名称
dlg.cCname = m_datagrid.GetItem(1);
dlg.m_Contact = m_datagrid.GetItem(2); //联系人
dlg.m_Address = m_datagrid.GetItem(3); //通信地址
dlg.m_Postcode = m_datagrid.GetItem(4); //邮政编码
dlg.m_Phone = m_datagrid.GetItem(5); //联系电话
dlg.m_Fax = m_datagrid.GetItem(6); //传真
dlg.m_Memo = m_datagrid.GetItem(7); //备注信息
if (dlg.DoModal() == IDOK)
Refresh_Data();
}
void CClientManDlg::OnDelButton()
{
// TODO: Add your control notification handler code here
if (m_adodc.GetRecordset().GetEof())
{
MessageBox("请选择要删除的记录");
return;
}
CString Cid;
Cid = m_datagrid.GetItem(0);
CStoreIn obj;
if (obj.HaveClient(Cid) == 1)
{
MessageBox("客户出现在入库单中,不能删除");
return;
}
CTakeOut obj1;
if (obj1.HaveClient(Cid) == 1)
{
MessageBox("客户出现在出库单中,不能删除");
return;
}
if (MessageBox("是否删除当前记录","请确定", MB_YESNO) == IDYES)
{
CClient clt;
clt.sql_delete(m_datagrid.GetItem(0));
Refresh_Data();
}
}
三、仓库信息管理

void CStoreHouseManDlg::Refresh_Data()
{
UpdateData(TRUE);
CString cSource;
cSource = "SELECT Sid, Sname AS 仓库单位, Memo AS 备注";
cSource += " FROM Storehouse ORDER BY Sname";
m_adodc.SetRecordSource(cSource);
m_adodc.Refresh();
//设置表格列宽度
_variant_t vIndex;
vIndex = long(0);
m_datagrid.GetColumns().GetItem(vIndex).SetWidth(0);
vIndex = long(1);
m_datagrid.GetColumns().GetItem(vIndex).SetWidth(100);
vIndex = long(2);
m_datagrid.GetColumns().GetItem(vIndex).SetWidth(420);
}
void CStoreHouseManDlg::OnAddButton()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
//打开编辑对话框
CStoreHouseEditDlg dlg;
dlg.cSid = "";
if (dlg.DoModal() == IDOK)
Refresh_Data();
}
void CStoreHouseManDlg::OnModiButton()
{
// TODO: Add your control notification handler code here
if (m_adodc.GetRecordset().GetEof())
{
MessageBox("请选择要修改的记录");
return;
}
UpdateData(TRUE);
CStoreHouseEditDlg dlg;
dlg.cSid = m_datagrid.GetItem(0); //记录编号
dlg.m_Sname = m_datagrid.GetItem(1); //仓库名称
dlg.m_Memo = m_datagrid.GetItem(2); //备注信息
if (dlg.DoModal() == IDOK)
Refresh_Data();
}
void CStoreHouseManDlg::OnDelButton()
{
// TODO: Add your control notification handler code here
if (m_adodc.GetRecordset().GetEof())
{
MessageBox("请选择要删除的记录");
return;
}
CString Sid;
Sid = m_datagrid.GetItem(0);