Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2096039
  • 博文数量: 909
  • 博客积分: 4000
  • 博客等级: 上校
  • 技术积分: 12260
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-06 20:50
文章分类

全部博文(909)

文章存档

2008年(909)

我的朋友

分类:

2008-05-06 21:32:20

一起学习
基于DAO的学生成绩管理软件


作者 刘永超


下载源代码


前面我已经写过几篇关于数据库的文档,这一篇还是它的后继篇。前面都是用ODBC开发的,现在改用DAO,DAO有一个缺点,没有同步支持ACCESS的最新版本,还要转换到早期的版本,不知道微软是咋搞的。废话少说,首先看一下软件的用法:
  • 1、对话框中有两个菜单项用于创建班级和增减科目,一项下面有两个子项。其中"增加班级"只有在选中对话框"组合控件"中的一个班级然后按"开始"按钮后,才可以使用,因为只有先得到表的结构,才能按此结构创建新表。而其它三个子项恰相反,只有程序刚打开还没有选择班级按"开始按钮"或选择"组合控件"中的"关闭班级"项按"开始"按钮后才可以使用,这是因为只有把所有班级记录集关闭后,这三项才能安全工作。
  • 2、增加记录与以前有一点不同,打开增加记录对话框后,大家可以看到不同,因为科目是随"增减科目"变化的,所以增加记录的科目要动态变化。
  • 3、修改记录只有选中列表控件中的一条记录后,按"修改记录"按钮才可以。
  • 4、其它的与以前版本相同。
下面看一下开发过程:
因为科目是可以变化的,所以我没有用一个具体的CDaoRecordset类,因此大部分的
功能是用SQL语句实现的。

1、首先看一下OnInitDialog():
BOOL CListDlg::OnInitDialog()

{

	CDialog::OnInitDialog();

   

    SetWindowText("学生成绩管理");

	// 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);

		}

	}

   



	SetIcon(m_hIcon, TRUE);			// Set big icon

	SetIcon(m_hIcon, FALSE);		// Set small icon



	GetDlgItem(IDC_STRAT)->EnableWindow(FALSE);

 this->Enable(FALSE);



	m_pDB=new CDaoDatabase;

	CString sPath;

	GetModuleFileName(NULL,sPath.GetBufferSetLength(MAX_PATH 1),MAX_PATH);

	sPath.ReleaseBuffer ();

	int nPos;

	nPos=sPath.ReverseFind (''\\'');

	sPath=sPath.Left (nPos);

	nPos=sPath.ReverseFind(''\\'');

    sPath=sPath.Left (nPos);

	CString lpszFile = sPath   "\\db6.mdb";

	try{

		m_pDB->Open(lpszFile);

	}

	catch(CDaoException* e)

	{

		AfxMessageBox(e->m_pErrorInfo->m_strDescription,MB_ICONEXCLAMATION);

		delete m_pDB;

		e->Delete();

		return FALSE;

	}

    

 CDaoTableDefInfo tabInfo;

	int nTableDefCount = m_pDB->GetTableDefCount();

	for (int i = 0; i < nTableDefCount; i  )

	{

		m_pDB->GetTableDefInfo(i,tabInfo);

		if (tabInfo.m_lAttributes & dbSystemObject)

			continue;

		m_Com.AddString(tabInfo.m_strName);



	}

	m_pRecordSet=new CDaoRecordset(m_pDB);

 m_bTF=TRUE;

	m_bCR=FALSE;

	return TRUE;  // return TRUE  unless you set the focus to a control

}      
它的主要任务是打开数据库和表的名字

2、下面是最为重要的OnStatr():
void CListDlg::OnStrat() 

{  

	if(m_pRecordSet->IsOpen())

    m_pRecordSet->Close();

  

    m_List1.DeleteAllItems();

    if(nField!=0)

	{

	for(long i=0;iOpen(dbOpenDynaset, strSQL);

		m_pRecordSet->m_strFilter.Empty();

	}

	catch(CDaoException *e)

	{   

		AfxMessageBox(e->m_pErrorInfo->m_strDescription,MB_ICONEXCLAMATION);

		delete m_pRecordSet;

		m_pDB->Close();

		delete m_pDB;

		e->Delete();

		return ;

	}

	 

	if(m_pRecordSet != NULL)

	{

		m_pImageList = new CImageList();

		m_pImageList->Create(IDB_BITMAP4, 16, 1, RGB(255,0,0));

		m_List1.SetImageList(m_pImageList, LVSIL_SMALL);	/* set extended stlyes*/

		

	DWORD dwExStyle = LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | /*LVS_EX_SUBITEMIMAGES |*/

		m_List1.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);

		LVS_EX_HEADERDRAGDROP | LVS_EX_TRACKSELECT;



		LV_COLUMN lvColumn;

		lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;

		lvColumn.fmt = LVCFMT_LEFT;	lvColumn.cx = 67;

	    nField=m_pRecordSet->GetFieldCount();

		for(int i = 0; i < nField; i  ) // set up columns

		{    

			CDaoFieldInfo m_fieldinfo;

			m_pRecordSet->GetFieldInfo(i, m_fieldinfo);//get field name

			int len = m_fieldinfo.m_strName.GetLength();

			CString temp = m_fieldinfo.m_strName;

			TCHAR* szBuffer = new TCHAR[len   1];

			strcpy(szBuffer, temp.GetBuffer(len));

			temp.ReleaseBuffer();

			lvColumn.pszText = szBuffer;

		    m_List1.InsertColumn(i, &lvColumn);//insert column		

			delete szBuffer;

		}

		/*set number of items in ListView*/

		m_pRecordSet->MoveFirst();

		m_pRecordSet->MoveLast();

     long count =m_pRecordSet->GetRecordCount();//Get number of records

	   this->OnGetdispinfoList( count, nField);

	

	}

	GetDlgItem(IDC_STRAT)->EnableWindow(FALSE);

	this->Enable(TRUE);

}      
3、而OnGetdispinfoList(long row,long column) 最为有用,可以在很多方面调用:
void CListDlg::OnGetdispinfoList(long row,long column) 

{  

   

	if(!m_pRecordSet)

	return;

    COleVariant varValue;

	for(long i=0;iSetAbsolutePosition(i);//Set the file to desired index



		}

		catch(CDaoException* e)

		{

		AfxMessageBox(e->m_pErrorInfo->m_strDescription, 

				    MB_ICONEXCLAMATION );

		e->Delete();

		return;

		}

	

    	for(long j=0;jGetFieldValue(j, varValue);

		   	 else

			 m_pRecordSet->GetFieldValue(0, varValue);

		}

		catch(CDaoException* e)

		{

			AfxMessageBox(e->m_pErrorInfo->m_strDescription, 

				    MB_ICONEXCLAMATION );

			e->Delete();

			return;

		}

	



		const VARIANT* variant = LPCVARIANT(varValue);

		

		if(variant->vt & VT_BYREF)

			return;

		CString st;

		switch(variant->vt)

		{  

			case VT_ERROR:{	

							st="Error";					

							break;

						  }

			case VT_I2:{ 	

				            st.Format("%d", variant->iVal);

							break;

					   }

			case VT_I4:{ 

				           st.Format( "%d", variant->lVal);

							break;

					   }

			case VT_R4:{   

						   st.Format( "%.2f", variant->fltVal);

                           

						    break;}

					

			case VT_R8:{	st.Format( "%.2f", variant->dblVal);

							break;

					   }

			case VT_CY:{	COleCurrency c(varValue);

						   st = c.Format();//ie. 1.00

							break;

					   }

			case VT_DATE:{	COleDateTime t(variant->date);

							st = t.Format( "%B %d, %Y" );//Day of Week, Month Day, Year

							

							break;

						 }

			case VT_BSTR:{   st = V_BSTRT( &varValue );//convert BSTR to CString

							

							break;

						}

			case VT_BOOL:{	if(variant->boolVal)

							st="TRUE";

							else

								st= "FALSE";

							break;

						 }

			case VT_UI1:{st=(CString)((char*)variant->bVal);

							break;

						}



				default:{

							

							break;

						}



		}

      if(j==0)		

      m_List1.InsertItem(i,st,0);

      else

      m_List1.SetItemText(i,j,st);

		}

  	}

}      
其它的可以看源码。
注意:
  • (1) 这个程序没有实现以前的成绩统计的功能,其实这些功能的实现不要用表,建按钮实现就可,比较简单,有兴趣可以一试。这里把重点放在"增减科目"上。
  • (2) 程序完后,时间紧张,没有优化,大家有兴趣可以优化一下。下一步,我的重点放在这上面,准备用COM把很多部分做成组件,欢迎有兴趣的读者和我交流。
  • (3) 界面也没有花时间美化。 下载本文示例代码


    基于DAO的学生成绩管理软件基于DAO的学生成绩管理软件基于DAO的学生成绩管理软件基于DAO的学生成绩管理软件基于DAO的学生成绩管理软件基于DAO的学生成绩管理软件基于DAO的学生成绩管理软件基于DAO的学生成绩管理软件基于DAO的学生成绩管理软件基于DAO的学生成绩管理软件基于DAO的学生成绩管理软件基于DAO的学生成绩管理软件
阅读(253) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~