课程设计报
家庭财务管理系统设计
姓名 学号 课程名称 指导教师
班级
2011年12月23日
1
目 录
1.家庭财务管理系统需求分析…………………………3 2.家庭财务管理系统数据库设计 ………………………3
2.1 数据库关系分析 ……………………………3 2.2 E-R图设计 …………………………………4 2.3 数据表的生成………………………………4 3. 家庭财务管理系统的算法设计……………………5 3.1连接数据库……………………………………5 3.2添加数据………………………………………5 3.3修改数据库内容………………………………6 3.4统计数据库信息………………………………6 4.软件项目开发过程 …………………………………6 4.1根据E-R图创建数据库表……………………7 4.2功能研发的准备工作…………………………7 4.3.1添加ADO连接的支持……………………8 4.3.2为界面添加控件…………………………8 4.3.3添加并修改OnInitDialog()类…………8 4.4 实现算法设计…………………………………12 4.4.1“添加”按钮的消息处理功能…………12 4.4.2“修改”按钮的消息处理功能…………13 4.4.3“统计”按钮的消息处理功能…………14 5.测试……………………………………………16
2
家庭财务管理系统
1.家庭财务管理系统需求分析
家庭财务管理系统相对于企业的财务系统而言,要简单得多,毕竟收支方面的流程和种类都比较小,而且使用该系统的管理员也比较少。为了简单起见,本项目就实现家庭财务管理系统的支出方面进行讲解分析。
家庭财务管理系统的概要功能如下:
可以对每天的支出进行记帐,记帐要实现分类: (1)按不同的支出类型分类。
(2)按不同的消费人员进行分类。
可以对历史数据进行查询,查询要实现的功能是:
(1)指定时间段,可以按类型进行该时间段的支出统计查询。
(2)指定时间段,可以按消费人员进行该时间段的支出统计查询。 (3)指定时间段,可以同时按类型和消费人员进行该时间段的支出统计查询。
根据前文所述的功能需求,在功能上可以分为两个模块: 记帐的功能。
查询并统计的功能。
因此,在操作界面上也应该分两个区域分别为这两个功能提供用户的操作界面:
日常功能:日常功能就是对日常的开支进行记帐。
统计功能:统计功能就是根据用户输入的起止时间,对特定的类型和消费人员的支出进行统计。
2.家庭财务管理系统的数据库设计 2.1数据关系分析
数据库的设计,首先应该从数据之间的相互关系入手。如果数据库系统比较复杂,则还需要进行规范化的项目管理流程,一般的数据库系统开发流程如下: (1)需求分析阶段
(2)概念结构设计阶段 (3)数据库详细设计阶段 (4)应用程序开发阶段 (5)数据库系统实施阶段
(6)数据库系统运行和维护阶段
3
2.2E-R图设计
概念模型就是对信息世界的抽象建模,狭义的信息世界可以专指数据库中的数据,那么概念模型就可以理解为对数据库数据的抽象建模。
概念模型最常用的描述方法是E-R图(“实体-联系”图)描述法,E-R图主要有3个要素:
实体:实体是以矩形表示。实体就是数据库数据中具有实际意义的主体,如在前文分析的实体就是“消费人员”和“消费品”。
属性:属性用椭圆表示。就是实体所拥有的特性,如果是在面向对象程序设计中,可以将“实体”和“属性”对应为“对象”和“对象中的数据成员”的关系。
联系:联系用菱形表示。联系是实体与实体之间发生的动作、从属或其他依赖关系。
2.3数据库表的生成
由E-R图生成数据库表是数据库系统研发的必要步骤,如果没有联系,只有单实体或孤立的实体的E-R图,转换方式很简单: (1)首先将实体名写成数据库表的表名。
(2)然后将实体的属性写成数据库表的属性。
(3)根据实际含义,将设定数据库属性的类型(整型、字符串型或日期类型等)。 (4)设定主码。
4
Budget表:
Handler表:
Type表:
3.家庭财务管理系统的算法设计 3.1连接数据库
连接数据库的功能是所有数据库应用系统开发的必要过程,本项目采用ADO的连接方式进行连接。连接数据库的过程如下: 初始化OLE,创建ADO连接。
调用Open()函数,打开本地的数据库文件“Home.mdb”。
为界面读取初始化数据,传递SQL语句选择出相应的数据库元组。
3.2添加数据
为数据库添加数据是数据库开发的重要功能,主要步骤如下: 调用Open()函数打开数据集。
调用AddNew()成员函数,告知系统开始添加数据。 添加数据操作。
调用Update()将添加的数据写回到磁盘的数据库文件中。 调用Close()成员函数关闭数据集。
5
3.3修改数据库内容
从应用程序种修改数据库的内容关键也在于传递SQL语句,使用SQL的更新语句即可,如下所示:
update 表名 set DateA='某日期',Content='某内容',MoneyA=某金额,Handler='某人',Type='某类型' where ID=某ID ;
将该SQL语句存放在strSql字符串变量中,然后再调用Execute()函数执行即可。代码如下:
m_pConnection->Execute(_bstr_t(strSql),&vAffected,adCmdText);
3.4统计数据库信息
统计数据库的信息关键在于使用SQL语句的集函数,就是对数据表中的某属性进行集操作,这里使用的集函数是“和”操作,即“SUM()”函数,代码如下:
select SUM(MoneyA) as SumMoneyA from Budget where DateA>=某日期 and DateA<=某日期 and Type=某消费品类型 and Handler= 某消费人 ;
4.软件项目开发过程
4.1开发家庭财务管理系统项目的流程
1 、创建数据库表结构2 、功能研发前的准备 工作 (ADO支持 、界面控件设置等 )
3 、根据算法设计 ,实现按钮功能6
4.2根据E-R图创建数据库表 如下所示:
4.3功能研发的准备工作
在实现系统的添加、修改和统计功能之前,需要做一些准备工作,使整个项目的数据库连接和访问等能顺利进行,并使界面可以达到预期目标。
准备工作的工作流程如图所示。
1 、添加ADO支持2 、为界面添加控件ID和与控件绑定的变量3 、添加并修改OnInitDialog()虚函数7
4.3.1为stdafx.h头文件添加ADO连接的支持
代码如下:
#import\"c:\\programfiles\\commonfiles\\system\\ado\\msado15.dll\" \\no_namespace \\
rename (\"EOF\
4.3.2为界面添加控件ID
界面如下:
4.3.3添加并修改OnInitDialog()类: 代码如下:
BOOL CHomeResDlg::OnInitDialog() {
CDialog::OnInitDialog();
// Add \"About...\" menu item to system menu.
8
// IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) {
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) {
pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } }
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon //
m_cobAnaType.AddString(\"全部类型\"); m_cobAnaHandler.AddString(\"全部人\"); m_cobAnaType.SetCurSel(0); m_cobAnaHandler.SetCurSel(0); GetSystemTime(&m_CurTime); m_CurTime.wDay = 1;
m_DateFrom.SetTime(&m_CurTime); m_CurTime.wMonth += 1;
m_DateTo.SetTime(&m_CurTime);
// 初始化COM,创建ADO连接等操作 AfxOleInit();
m_pConnection.CreateInstance(__uuidof(Connection));
// 在ADO操作中建议语句中要常用try...catch()来捕获错误信息,
// 因为它有时会经常出现一些意想不到的错误。jingzhou xu try {
9
// 打开本地Access库Demo.mdb
m_pConnection->Open(\"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Home.mdb\ }
catch(_com_error e) {
AfxMessageBox(\"数据库连接失败,确认数据库Demo.mdb是否在当前路径下!\"); return FALSE; }
//从数据库中读入经手人名单和类型名单 _RecordsetPtr pHandlerRecordset;
pHandlerRecordset.CreateInstance(__uuidof(Recordset)); try {
pHandlerRecordset->Open(\"SELECT * FROM Handler\ // 查询DemoTable表中所有字段
m_pConnection.GetInterfacePtr(), // 获取库接库的IDispatch指针
adOpenDynamic, adLockOptimistic, adCmdText); }
catch(_com_error *e) {
AfxMessageBox(e->ErrorMessage()); }
_variant_t var; CString strName;
while(!pHandlerRecordset->adoEOF) {
var = pHandlerRecordset->GetCollect(\"Handler\"); if(var.vt != VT_NULL)
strName = (LPCSTR)_bstr_t(var); m_cobHandle.AddString(strName); m_cobAnaHandler.AddString(strName); pHandlerRecordset->MoveNext(); }
pHandlerRecordset->Close(); pHandlerRecordset.Release(); pHandlerRecordset = NULL;
10
////////////////////////////////////////////////////////////////////////// CString strType;
_RecordsetPtr pTypeRecordset;
pTypeRecordset.CreateInstance(__uuidof(Recordset)); try {
pTypeRecordset->Open(\"SELECT * FROM Type\ // 查询DemoTable表中所有字段
m_pConnection.GetInterfacePtr(), // 获取库接库的IDispatch指针
adOpenDynamic, adLockOptimistic, adCmdText); }
catch(_com_error *e) {
AfxMessageBox(e->ErrorMessage()); }
while(!pTypeRecordset->adoEOF) {
var = pTypeRecordset->GetCollect(\"Type\"); if(var.vt != VT_NULL)
strType = (LPCSTR)_bstr_t(var); m_cobType.AddString(strType); m_cobAnaType.AddString(strType); pTypeRecordset->MoveNext(); }
pTypeRecordset->Close(); pTypeRecordset.Release(); pTypeRecordset = NULL;
//读入当月的记录 //
CTime Today = CTime::GetCurrentTime();
Load(Today.GetMonth(),Today.GetMonth() + 1); m_nHandler = 0; m_nType = 0;
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
11
}
4.4实现算法设计
根据前文所创建的项目,在项目的对话框中设计出前文所示的界面设计。界面上主要的功能按钮有:
“添加”按钮:单击该按钮后,将对话框编辑控件的内容添加到数据库。
“修改”按钮:单击该按钮后,使对话框编辑控件中与数据库对应的内容作出相应的修改。
“统计”按钮:单击该按钮后,对指定时间段内的数据库内容,分消费品的经手人或消费品种类进行统计,并将统计结果显示在对话框相应的控件中。
4.4.1“添加”按钮的消息处理功能
双击“添加”按钮,添加该按钮的消息处理函数,代码如下:
void CHomeResDlg::OnBtnAdd() {
UpdateData();
_RecordsetPtr m_pRecordset;
m_pRecordset.CreateInstance(__uuidof(Recordset)); try {
m_pRecordset->Open(\"SELECT * FROM Budget\ // 查询DemoTable表中所有字段
m_pConnection.GetInterfacePtr(), // 获取库接库的IDispatch指针
adOpenDynamic, adLockOptimistic, adCmdText); }
catch(_com_error *e) {
AfxMessageBox(e->ErrorMessage()); }
CString strDate,strType,strHandler;
GetDlgItem(IDC_DATETIMEPICKER_DATE)->GetWindowText(strDate);
m_cobType.GetWindowText(strType);
m_cobHandle.GetWindowText(strHandler);
12
//添加新记录
m_pRecordset->AddNew();
m_pRecordset->PutCollect(\"DateA\ m_pRecordset->PutCollect(\"Content\ent));
m_pRecordset->PutCollect(\"MoneyA\_variant_t(m_fMoney));
m_pRecordset->PutCollect(\"Handler\_variant_t(strHandler));
m_pRecordset->PutCollect(\"Type\ m_pRecordset->Update();
m_pRecordset->Close(); m_pRecordset = NULL;
CTime Today = CTime::GetCurrentTime();
Load(Today.GetMonth(),Today.GetMonth() + 1); }
4.4.2“修改”按钮的消息处理功能
双击“修改”按钮,添加该按钮的消息处理函数,代码如下: void CHomeResDlg::OnBtnModify() {
//Load(m_tDate.GetMonth(),m_tDate.GetMonth() + 1); UpdateData(); if(m_lCurID > 0) {
int nCurSel = 0; int nID = 0;
CString strDate,strType,strHandler; m_Date.GetWindowText(strDate); m_cobType.GetWindowText(strType);
m_cobHandle.GetWindowText(strHandler); CString strSql;
strSql.Format(\"update Budget set DateA='%s',Content='%s',MoneyA=%f,Handler='%s',Type='%s' where ID=%d\
strDate,m_strContent,m_fMoney,strHandler,strType,m_lCurID);
_variant_t vAffected;
13
m_pConnection->Execute(_bstr_t(strSql),&vAffected,adCmdText);
CTime Today = CTime::GetCurrentTime();
Load(Today.GetMonth(),Today.GetMonth() + 1);
} }
4.4.3“统计”按钮的消息处理功能
双击“统计”按钮,添加该按钮的消息处理函数,代码如下:
void CHomeResDlg::OnBtnAna() {
CString
strAnaType,strAnaHandler,strDateFrom,strDateTo;
m_DateFrom.GetWindowText(strDateFrom); m_DateTo.GetWindowText(strDateTo);
m_cobAnaType.GetWindowText(strAnaType);
m_cobAnaHandler.GetWindowText(strAnaHandler); CString strSql,strTemp;
strSql.Format(\"select SUM(MoneyA) as SumMoneyA from Budget where DateA>=#%s# and DateA<=#%s#\
strDateFrom,strDateTo); if(strAnaType != \"全部类型\") {
strTemp.Format(\" and Type='%s'\ strSql += strTemp; }
if(strAnaHandler != \"全部人\") {
strTemp.Format(\" and Handler='%s'\ strSql += strTemp; }
strTemp.Format(\"时间:%s-> %s\ m_ResList.AddString(strTemp);
14
strTemp.Format(\"类型:%s\ m_ResList.AddString(strTemp);
strTemp.Format(\"经手人:%s\ m_ResList.AddString(strTemp);
_RecordsetPtr SumRecordset; _variant_t vSum; /*
SumRecordset.CreateInstance(__uuidof(Recordset)); try {
SumRecordset->Open(_bstr_t(strSql), // 查询DemoTable表中所有字段
m_pConnection.GetInterfacePtr(), // 获取库接库的IDispatch指针
adOpenDynamic, adLockOptimistic, adCmdText); }
catch(_com_error *e) {
AfxMessageBox(e->ErrorMessage()); } */
SumRecordset = m_pConnection->Execute(_bstr_t(strSql),&vSum,adCmdText);
while(!SumRecordset->adoEOF) {
vSum = SumRecordset->GetCollect(\"SumMoneyA\"); if(vSum.vt != VT_NULL) {
strTemp.Format(\"总计:¥%.2f元\ m_ResList.AddString(strTemp); } else {
m_ResList.AddString(\"总计:¥0.00元\"); }
SumRecordset->MoveNext(); }
SumRecordset->Close();
m_ResList.AddString(\"----------------\"); }
15
5.测试
本小节对“HomeRes”项目进行测试,按F5键编译并运行项目,测试流程如下:
(1)测试添加功能。 (2)测试统计功能。 (3)测试修改功能。
在日常功能中,选中与添加功能的数据组合相同的数据,对金额进行修改,修改后,按照测试统计功能的数据组合再进行统计,查看并思考统计结果的变化。
在软件工程项目开发过程中,软件测试是软件生命周期中质量保证的关键环节,任何软件都不可能做到十全十美,而编译器也只负责检查语法错误,而对于逻辑错误则为力了,因此软件测试对于成功开发软件至关重要。
16
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- haog.cn 版权所有 赣ICP备2024042798号-2
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务