⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 studentdoc.cpp

📁 学生成绩查询系统.帮忙大家学生和提升对VC++的学生和认识.
💻 CPP
字号:
// StudentDoc.cpp : implementation of the CStudentDoc class
//

#include "stdafx.h"
#include "Student.h"

#include "StudentDoc.h"
#include "DlgQuery.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CStudentDoc

IMPLEMENT_DYNCREATE(CStudentDoc, CDocument)

BEGIN_MESSAGE_MAP(CStudentDoc, CDocument)
	//{{AFX_MSG_MAP(CStudentDoc)
	ON_COMMAND(ID_PROCESS_QUERY, OnProcessQuery)
	ON_COMMAND(ID_PROCESS_SORT, OnProcessSort)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CStudentDoc construction/destruction

CStudentDoc::CStudentDoc()
{
	// TODO: add one-time construction code here

}

CStudentDoc::~CStudentDoc()
{
}

BOOL CStudentDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)

	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CStudentDoc serialization

void CStudentDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

/////////////////////////////////////////////////////////////////////////////
// CStudentDoc diagnostics

#ifdef _DEBUG
void CStudentDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CStudentDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CStudentDoc commands

void CStudentDoc::OnProcessQuery()		// “处理/查询”菜单命令对应的消息处理函数 
{
	// TODO: Add your command handler code here
	CDatabase database;						// 声明数据库对象
	CRecordset* pRecordset;					// 声明记录集指针
	CString strSQL;							// 声明MFC之字符串类的对象,存放用于数据库查询的SQL语句
	CDBVariant dbv;							// 声明代表MFC之ODBC类中的变体类型的对象
	string id, name;
	float exercise, report, midterm, terminal;
	CString str;
	int i, n;
	CDlgQuery dlg;							// 声明用于查询班级和课程的对话框对象

	// 打开数据源(Access数据库)
	if (!database.Open(_T("ODBC;DSN=MS Access Database")))
	{
		AfxMessageBox("不能打开数据源!");
		return;
	}

	pRecordset = new CRecordset(&database);	// 创建存放数据的记录集

	strSQL = "SELECT 班级名称 FROM 班级;";	// 创建查询班级的SQL语句

	// 用SQL查询数据库,将数据存放于记录集中
	if (!pRecordset->Open(CRecordset::forwardOnly, strSQL, CRecordset::readOnly))
	{
		AfxMessageBox("不能打开记录集!");
		delete pRecordset;
		database.Close();
		return;
	}

	// 扫描记录集,确定班级数目
	dlg.m_lstClass.nodeNum = 0;
	while (!pRecordset->IsEOF())
	{
		pRecordset->GetFieldValue("班级名称", str);
		pRecordset->MoveNext();
		dlg.m_lstClass.nodeNum ++;
	}
	pRecordset->Close();

	// 创建对话框对象中用于存放班级名称的数组
	dlg.m_lstClass.pStrArr = new CString[dlg.m_lstClass.nodeNum];
	// 用SQL查询数据库,将班级名称存放于记录集中
	pRecordset->Open(CRecordset::forwardOnly, strSQL, CRecordset::readOnly);
	// 从记录集中取出班级名称,存放于对话框对象的数组中
	for (i = 0; i < dlg.m_lstClass.nodeNum; i ++)
	{
		pRecordset->GetFieldValue("班级名称", str);
		dlg.m_lstClass.pStrArr[i] = str;
		pRecordset->MoveNext();
	}
	pRecordset->Close();

	strSQL = "SELECT 课程名称 FROM 课程;";	// 创建查询课程的SQL语句

	// 用SQL查询数据库,将数据存放于记录集中
	pRecordset->Open(CRecordset::forwardOnly, strSQL, CRecordset::readOnly);

	// 扫描记录集,确定课程数目
	dlg.m_lstCourse.nodeNum = 0;
	while (!pRecordset->IsEOF())
	{
		pRecordset->GetFieldValue("课程名称", str);
		pRecordset->MoveNext();
		dlg.m_lstCourse.nodeNum ++;
	}
	pRecordset->Close();

	// 创建对话框对象中用于存放课程名称的数组
	dlg.m_lstCourse.pStrArr = new CString[dlg.m_lstCourse.nodeNum];
	// 用SQL查询数据库,将课程名称存放于记录集中
	pRecordset->Open(CRecordset::forwardOnly, strSQL, CRecordset::readOnly);
	// 从记录集中取出课程名称,存放于对话框对象的数组中
	for (i = 0; i < dlg.m_lstCourse.nodeNum; i ++)
	{
		pRecordset->GetFieldValue("课程名称", str);
		dlg.m_lstCourse.pStrArr[i] = str;
		pRecordset->MoveNext();
	}
	pRecordset->Close();

	// 弹出对话框选择班级和课程,如果都已选择,则用选中的班级和课程生成SQL语句
	if (dlg.DoModal() == IDOK && dlg.m_selClass >= 0 && dlg.m_selCourse >= 0)
	{
		m_Class = dlg.m_lstClass.pStrArr[dlg.m_selClass];
		m_Course = dlg.m_lstCourse.pStrArr[dlg.m_selCourse];
		strSQL = "SELECT 学生.学号, 学生.姓名, 成绩.平时作业, 成绩.实验报告, 成绩.期中考试, 成绩.期末考试 ";
		strSQL += "FROM (班级 INNER JOIN 学生 ON 班级.班级ID = 学生.班级ID) INNER JOIN (课程 INNER JOIN 成绩 ON 课程.课程ID = 成绩.课程ID) ON 学生.学生ID = 成绩.学生ID ";
		strSQL += "WHERE 班级.班级名称='";
		strSQL += m_Class;
		strSQL += "' AND 课程.课程名称='";
		strSQL += m_Course;
		strSQL += "'";

		// 用SQL查询数据库,将数据存放于记录集中
		pRecordset->Open(CRecordset::forwardOnly, strSQL, CRecordset::readOnly);

		// 对记录集进行扫描以确定记录数
		i = 0;
		while (!pRecordset->IsEOF())
		{
			pRecordset->MoveNext();
			i ++;
		}
		pRecordset->Close();
		n = i;

		// 如果记录集不空,则逐个取出记录,将字段转储到变量,然后用变量对对象数组元素进行赋值
		if (n > 0)
		{
			Student2* pStudent = new Student2[n];			// 创建一个Student派生类对象数组
			pRecordset->Open(CRecordset::forwardOnly, strSQL, CRecordset::readOnly);
			for (i = 0; i < n; i++)
			{
				pRecordset->GetFieldValue("学号", str);		// 取出记录
				id = str;									// 转储到C++字符串变量,下同
				pRecordset->GetFieldValue("姓名", str);
				name = str;
				pRecordset->GetFieldValue("平时作业", dbv);	// 取出记录
				exercise = dbv.m_fltVal;					// 转储到浮点变量,下同
				pRecordset->GetFieldValue("实验报告", dbv);
				report = dbv.m_fltVal;
				pRecordset->GetFieldValue("期中考试", dbv);
				midterm = dbv.m_fltVal;
				pRecordset->GetFieldValue("期末考试", dbv);
				terminal = dbv.m_fltVal;
				pStudent[i].SetStudent(id, name, exercise, report, midterm, terminal);	// 用变量为对象数组元素赋值
				pStudent[i].CalcMark();													// 对数组元素计算总评成绩
				pRecordset->MoveNext();
			}
			pRecordset->Close();							// 关闭记录集
			m_studentlist.SetStudentList(pStudent, n);		// 用数组为Student派生类对象的线性表赋值
			delete[] pStudent;								// 删除Student派生类对象数组
		}
		else		// 如果记录集为空,则创建只有一个元素的线性表(数据为空或0)
		{
			Student2* pStudent = new Student2[1];
			id = name = "";
			exercise = report = midterm = terminal = 0;
			pStudent[0].SetStudent(id, name, exercise, report, midterm, terminal);
			pStudent[0].CalcMark();
			m_studentlist.SetStudentList(pStudent, 1);
			delete[] pStudent;
		}
	}
	else		// 如班级和课程未同时选中,则弹出错误提示
	{
		AfxMessageBox("查询成绩须同时选定一个班级和一门课程。");
	}

	delete pRecordset;						// 删除记录集
	database.Close();						// 关闭数据库

	delete[] dlg.m_lstClass.pStrArr;		// 删除对话框对象中用于存放班级名称的数组
	delete[] dlg.m_lstCourse.pStrArr;		// 删除对话框对象中用于存放课程名称的数组

	UpdateAllViews(NULL, 0);				// 刷新视图、显示数据
}

void CStudentDoc::OnProcessSort() 		// “处理/排序”菜单命令对应的消息处理函数
{
	// TODO: Add your command handler code here
	if (m_studentlist.GetnStudent() && (m_Period >= 0 && m_Period <= 4)) // 如果阶段选择正确
	{
		m_studentlist.BubSort(m_Period);	// 则按指定考核阶段对应的成绩对线性表排序
		UpdateAllViews(NULL, 0);			// 刷新视图
	}
	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -