学生成绩管理系统详细设计说明书
1,引言:
1.1编写目的:
明细学生成绩管理系统软件的开发途径和应用方法
1.2背景及范围:
项目名称:学生成绩管理系统
项目任务:具体化、合理化地管理学生的学生成绩档案
1.3参考资料:
《软件工程导论》
1.4需求分析:
以学生成绩管理者的需求的出发点,设计方便成绩管理的系统,同时做到良好的交互性。
① 增加,删除,修改学生基本信息与成绩
② 动态添加与修改课程信息
③ 用户可自定义多条件查询
④ 实现不同分数段人数的统计图(柱状图,折线图,饼状图)显示
⑤ 读取课程信息文件与学生信息文件
⑥ 学生基本信息与成绩的保存与加载
⑦ 计算学生加权平均分并生成学生成绩排名表
⑧ 成绩表、课程信息表、排名表视图
2,设计明细与测试
2.1数据流
数据流图1-1:
数据流图1-2
2.2设计明细:
2.2.1工程说明
本程序基于SDI 并且视图类继承CFormView类。
SDI结构下面板类对象,视图类对象,应用程序类对象的获得方法
CSJ4App *app=(CSJ4App*)AfxGetApp();
CMainFrame* pMain=(CMainFrame*)AfxGetMainWnd();
CSJ4View* vv =(CSJ4View*) pMain->GetActiveView();
以上代码实现三个层次类对象的调用,有利于实现三个层次的交互。
注:工程名:SJ4,程序中应用到GDI+接口,在include 目录下拷入gdiplus.h,lib目录下拷入gdiplus.lib文件,同时,VC环境中设置library modules:gdiplus.lib
2.2.2类的说明
CCourse:课程类
class CCourse
{
public:
vector<CString> courses_name;//课程名称
vector<CString> courses_credit;//课程学分
vector<CString> teachers_name;//课程任课教师
Bool AddSubject(CString subname,CString teacher_name,CString credit);// 插入科目,三个参数分别为名称,任课教师,学分
CCourse();
virtual ~CCourse();
};
Cstudent:学生类
class Cstudent
{
public:
CString id;//学号
CString name;//姓名
int male;//性别
vector<CString> subs_name;//课程
vector<CString> subs_scores;//成绩表
Cstudent();
virtual ~Cstudent();
};
以及CTongjiDlg ,CQueryDlg,CNotifyDlg等对话框类
2.2.3变量与方法声明
2.2.3.1 App类对象:
变量名与类型 |
说明 |
int subs_size; |
科目数量 |
CCourse course; |
课程类对象 |
vector<Cstudent> stu_scores_link; |
学生类对象列表 |
vector<int> sort_result; |
加权排名列表 |
vector<int> query_result_link; |
查询结果列表 |
vector<double> avg; |
加权平均分界线列表 |
Void AddStudent() |
添加记录 |
Void Delete() |
删除记录 |
Void Motify() |
修改记录 |
2.2.3.2 App类方法
返回值、方法名与参数 |
说明 |
void flush(); |
刷新成绩列表 |
void flush_sort(); |
刷新排序列表 |
void flush_query(); |
刷新查询结果列表 |
void sort() |
对加权排序 |
2.2.3.3 View类对象
变量名与类型 |
说明 |
CMSFlexGrid m_fgrid; |
学生成绩表 |
CMSFlexGrid m_cgrid; |
课程信息表 |
CMSFlexGrid m_sort_grid; |
成绩排序表 |
int currentshow; |
当前显示状态 |
2.2.3.4 View类方法
void InitGrid(); |
初始化flexgrid列表的行数与列数 |
Virtual BOOL PreCreateWindow(CREATESTRUCT& cs); |
实现程序启动画面显示 |
int CSJ4View::OnCreate(LPCREATESTRUCT lpCreateStruct) |
初始化列表,其中包括各表第一行表头的值 |
void Ontongji(); |
显示统计对话框,并初始化 |
void OnMotify_Stu(); |
显示修改学生记录对话框,并初始化 |
Void OnNotify_COR() |
显示修改课程信息对话框,并初始化 |
|
显示添加对话框,并初始化 |
void Ondelete() |
显示删除确定提示框 |
void Onaddsub() |
显示添加课程对话框,并初始化 |
Void OnDrawPanel() |
显示分布图画板,并初始化 |
初始化过程包括:根据课程信息对combobox,TextField的初始化
2.3模块设计
2.3.1 多条件查询视图的实现模块:
点击添加条件后动态生成条件选择:
实现以上要求有两种方式:
① 设置控件可见性:Item->ShowWindow(int),参数为1表示可见,0表示隐藏
② 动态创建控件:
CComboBox *subs=new CComboBox;//为按钮对象指针分配空间
CStatic *st=new CStatic[courses_size];//分配多个对象空间
sub_box->Create(WS_CHILD|WS_VISIBLE|WS_VSCROLL|CBS_DROPDOWNLIST,CRect(20,80+(cons_size-1)*25,90,170+(cons_size-1)*25), this, cons_size+666);
cons_size为用户所添加的条件个数,初始化为1,当点击添加条件时加1,同时利用此变量设置控件的ID与位置。
//在相应位置上创建控件,参数分别为Style,位置,父窗口, ID
subs->Create(WS_CHILD|WS_VISIBLE|WS_VSCROLL|CBS_DROPDOWNLIST,CRect(95,80+(cons_size-1)*25,210,170+(cons_size-1)*25), this, cons_size+777);
2.3.2 分布图实现模块:
方法一:利用CTChart类
首先,在工程在添加控件,TeeChart Pro ActiveX Control
CTChart *m_c=(CTChart*)GetDlgItem(IDC_TCHART1);//新建对象
m_c->ClearChart();//清除图表
m_c->AddSeries(1);//添加系列,0系列为柱状图,5系列为饼图
m_c->Series(0).Add(tongji[0],"0-60",RGB(255,0,0));
//参数分别为:数值,名称,颜色
m_c->Series(0).Add(tongji[0],"0-60",RGB(255,0,0));
m_c->Series(0).Add(tongji[1],"60-70",RGB(0,255,0));
m_c->Series(0).Add(tongji[2],"70-80",RGB(0,0,255));
m_c->Series(0).Add(tongji[3],"80-90",RGB(120,0,0));
m_c->Series(0).Add(tongji[4],"90-100",RGB(0,100,0));
为Comobo Box添加消息映射,当getcursel(当前选择项)改变时重画。
方法二:利用CDC类画图:
CDC *pDC=GetDC();//获取DC
CBrush brush;//声明画刷
//获取app类对象
CSJ4App *app=(CSJ4App*)AfxGetApp();
//创建画刷 brush.CreateSolidBrush(RGB(255,255,255));
//以白色画背景
pDC->FillRect(CRect(0,0,330,320),&brush);
brush.DeleteObject();
//原点
CPoint zero(10,300);
//XY轴递增单位量
int offsetx=60,offsety=30;
int count=10;
CPen pen;
//创建画笔
pen.CreatePen(PS_SOLID,1.5,RGB(0,0,0));
//选择画笔
pDC->SelectObject(&pen);
//输入X轴
pDC->TextOut(zero.x+10,zero.y,"0-60");
pDC->TextOut(zero.x+70,zero.y,"60-70");
pDC->TextOut(zero.x+130,zero.y,"70-80");
pDC->TextOut(zero.x+190,zero.y,"80-90");
pDC->TextOut(zero.x+250,zero.y,"90-100");
//移动到原点
pDC->MoveTo(zero);
//画两轴
pDC->LineTo(zero.x,zero.y-280);
pDC->LineTo(zero.x-5,zero.y-275);
pDC->MoveTo(zero.x,zero.y-280);
pDC->LineTo(zero.x+5,zero.y-275);
pDC->MoveTo(zero);
pDC->LineTo(zero.x+500,zero.y);
pDC->LineTo(zero.x+495,zero.y+5);
pDC->MoveTo(zero.x+500,zero.y);
pDC->LineTo(zero.x+495,zero.y-5);
CRect *rect=new CRect(zero.x,zero.y-offsety,zero.x+offsetx,zero.y);
//获得学生记录数
int stu_size=app->stu_scores_link.size();
int i,j;
int tongji[5]={0};
//统计人数
for(i=0;i<stu_size;i++)
{ int score=atoi(app->stu_scores_link.at(i).subs_scores.at(cursel));
if(score<60)tongji[0]++;
else if(score>=60&&score<70)tongji[1]++;
else if(score>=70&&score<80)tongji[2]++;
else if(score>=80&&score<90)tongji[3]++;
else if(score>=90)tongji[4]++;
}
//百分比
double percent[5];
for(j=0;j<5;j++)
percent[j]=(double)tongji[j]/stu_size;
int top_leftx,top_lefty,bom_rightx,bom_righty,height=300;
for(i=0;i<5;i++)
{
//计算出各个柱状图的左上角右下角坐标
top_leftx=zero.x+i*offsetx;
top_lefty=zero.y-height*percent[i];
bom_rightx=zero.x+(i+1)*offsetx;
bom_righty=zero.y;
brush.CreateSolidBrush(RGB(128-i*15,128+i*15,i*30));
pDC->SelectObject(&brush);
rect->SetRect(top_leftx,top_lefty,bom_rightx,bom_righty);
CString per;
per.Format("%2.3f",percent[i]*100);
pDC->TextOut(top_leftx+10,top_lefty-30,per);
pDC->Rectangle(rect);
brush.DeleteObject();
}
MSFlexgrid控件的操作:初始化为控件m_fgrid设置列数与行数:
m_fgrid.SetCols(int);
m_fgrid.SetRows(int);
m_fgrid.SetTextMatrix(int col,int row,CString value);//为col行,row列赋值value
m_fgrid.SetBackColor(RGB(221,242,215));//设置背景颜色
2.3.3 多条件查询算法(实现任意数量条件的查询):
2.3.3.1 流程图:
2.3.3.2 详细代码见附1
2.3.4 文档串行化模块:关键在于读取与写入文件时的顺序
void CSJ4Doc::Serialize(CArchive& ar)
{
//保存状态
if (ar.IsStoring())
{
int i,j;
CSJ4App *app=(CSJ4App*)AfxGetApp();
int subs_size=app->course.courses_name.size();
//首先写入的是课程数
ar<<subs_size;
//接着写入课程信息
for(i=0;i<subs_size;i++)
ar<<app->course.courses_name.at(i)<<app->course.courses_credit.at(i)<<app->course.teachers_name.at(i);
//继续写入成绩记录数
int stus_size=app->stu_scores_link.size();
ar<<stus_size;
//最后写入每条记录的信息
for(i=0;i<stus_size;i++)
{
ar<<app->stu_scores_link.at(i).id;
ar<<app->stu_scores_link.at(i).name;
ar<<app->stu_scores_link.at(i).male;
for(j=0;j<subs_size;j++)
ar<<app->stu_scores_link.at(i).subs_scores.at(j);
}
}
//读取状态
else
{
//按上述顺序读取
int i,j;
CSJ4App *app=(CSJ4App*)AfxGetApp();
int subs_size;
ar>>subs_size;
CCourse *course=new CCourse;
CString c_n,c_c,c_t;
for(i=0;i<subs_size;i++)
{ ar>>c_n>>c_c>>c_t;
course->courses_name.push_back(c_n);
course->courses_credit.push_back(c_c);
course->teachers_name.push_back(c_t);
}
app->course=*course;
int stus_size;
ar>>stus_size;
CString id,name,score;
int male;
for(j=0;j<stus_size;j++)
{
Cstudent *stu=new Cstudent;
ar>>id>>name>>male;
stu->id=id;
stu->name=name;
stu->male=male;
for(i=0;i<subs_size;i++)
{ ar>>score;
stu->subs_scores.push_back(score);
}
app->stu_scores_link.push_back(*stu);
delete stu;
}
//读取完毕后刷新表格
app->subs_size=subs_size;
app->flush();
}
}
2.3.5 程序启动画面: 利用无模式对话框显示启动画面
在资源中新建一个对话框,创建对话框类CSplashDlg。在对话框中添加一个Picture控件,打开其“Properties”对话框,选General,在Type下拉列表中选择Bitmap,在Image下拉列表中选前面导入的位图资源ID值:IDB_SPLASH。
修改对话框的显示效果
①调整对话框大小,去掉两个自动生成的按钮,并在“Properties”的“Styles”页中去掉对Title bar的选取;
②选中图像,调整大小使之适应对话框的可编辑区,修改其“Properties”的“Styles”
使之居中。
添加代码:
BOOL CSJ4View::PreCreateWindow(CREATESTRUCT& cs)
{
CSplash *dlg = new CSplash(this);
dlg->Create(IDD_SPLASH,this); //创建对话框
dlg->ShowWindow(SW_SHOW); //显示对话框
dlg->UpdateWindow();
Sleep(1000); //画面显示停留时间,单位为毫秒
dlg->DestroyWindow(); //销毁对话框
eturn TRUE;
}
2.3.6删除模块:vector类没有提供删除指定元素而后续元素前移的函数,此方法代之实现.
Cstudent CSJ4App::Delete(int index)
{
Cstudent *stu=new Cstudent;
*stu=stu_scores_link.at(index);
vector<Cstudent> temp;
for(int i=0;i<this->stu_scores_link.size();i++)
if(i!=index)
temp.push_back(this->stu_scores_link.at(i));
this->stu_scores_link.clear();
this->stu_scores_link=temp;
return *stu;
}
2.3.7 修改模块:
void CSJ4View::OnNotify()
{
CSJ4App *app=(CSJ4App*)AfxGetApp();
//当前状态是修改学生表
if(this->currentshow==STUDENTTABLE){
int sel=this->m_fgrid.GetRowSel();
//如果选择的行不合理,返回
if(sel>app->stu_scores_link.size()||sel==0)return;
//创建无模式对话框
CInsert *pDialog=new CInsert();
BOOL ret = pDialog->Create(IDD_DIALOG1,this);
CString s;
int courses_size=app->course.courses_name.size();
int j=0;
//动态创建课程是本程序的特色所在,可以实现本系统的极强的通用性,因为从始至终都是根据用户自己创建的课程表来操作
CStatic *st=new CStatic[courses_size];
CComboBox *sub_box=new CComboBox[courses_size];
for(j=0;j<courses_size;j++)
{
//创建第j个,共有course_size 个
(st+j)->Create(_T(app->course.courses_name.at(j)), WS_CHILD|WS_VISIBLE, CRect(20,100+j*23,150,150+j*23), pDialog);
(sub_box+j)->Create(WS_CHILD|WS_VISIBLE|WS_VSCROLL|CBS_DROPDOWNLIST,CRect(110,100+j*23,160,150+j*23+60), pDialog, j+555);
for(int i=0;i<=100;i++)
{
s.Format("%d",i);
(sub_box+j)->InsertString(i,s);
}
(sub_box+j)->SetCurSel(atoi(app->stu_scores_link.at(sel-1).subs_scores.at(j)));
}
pDialog->m_id=app->stu_scores_link.at(sel-1).id;
pDialog->m_name=app->stu_scores_link.at(sel-1).name;
pDialog->m_m=app->stu_scores_link.at(sel-1).male;
pDialog->SetDlgItemText(IDOK,"Change");
CButton *btn=(CButton*)pDialog->GetDlgItem(IDC_BUTTON1);
btn->ShowWindow(0);
pDialog->SetWindowText("修改");
pDialog->UpdateData(false);
pDialog->opt=CHANGE;
pDialog->changeid=sel;
pDialog->ShowWindow(SW_SHOW);
}
//当前状态是修改课程表
else if(this->currentshow==COURSETABLE){
int sel=this->m_cgrid.GetRowSel();
if(sel>app->course.courses_name.size()||sel==0)return;
CChangeCourse *pDialog=new CChangeCourse();
BOOL ret = pDialog->Create(IDD_CHANGEC,this);
pDialog->sel=sel;
pDialog->ShowWindow(1);
pDialog->m_ccredit=app->course.courses_credit.at(sel-1);
pDialog->m_cname=app->course.courses_name.at(sel-1);
pDialog->m_cteacher=app->course.teachers_name.at(sel-1);
pDialog->UpdateData(false);
}
}
2.3.8 查询模块:
2.3.8.1模糊查询
void CChaxun::Onmhchaxun()
{
CSJ4App *app=(CSJ4App*)AfxGetApp();
UpdateData();
if(this->m_name=="")return;
app->query_result_link.clear();
int stusize=app->stu_scores_link.size();
for(int i=0;i<stusize;i++)
{
if(-1!=app->stu_scores_link.at(i).name.FindOneOf(m_name))
app->query_result_link.push_back(i);
}
app->flush_query();
}
2.3.8.2精确查询
void CChaxun::OnJQchaxun()
{
CSJ4App *app=(CSJ4App*)AfxGetApp();
UpdateData();
if(this->m_name=="")return;
app->query_result_link.clear();
int stusize=app->stu_scores_link.size();
for(int i=0;i<stusize;i++)
{
if(app->stu_scores_link.at(i).name==m_name)
app->query_result_link.push_back(i);
}
app->flush_query();
}
2.3.9 读取课程信息文件模块:
void CSJ4View::OnReadini()
{
CString m_strFileName;
CSJ4App *app=(CSJ4App*)AfxGetApp();
CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, "*.ini" );
if(dlg.DoModal()==IDOK)
{ m_strFileName=dlg.GetPathName();
if(m_strFileName=="")return;
}
else
return;
app->ini_address=m_strFileName;
CStdioFile file;
file.Open(m_strFileName,CFile::modeRead,NULL);
CString csline;
file.ReadString(csline);
if(csline!="version 1.0"){MessageBox("new version was found!");return;}
while(file.ReadString(csline)!=NULL)
{
csline.TrimLeft();
csline.TrimRight();
if(csline!="")
{
if(csline=="[SUBJECT]")
{file.ReadString(csline);app->course.courses_name.push_back(csline);
app->stu.subs_name.push_back(csline);
app->subs_size++;
}
else if(csline=="[TEACHER]"){file.ReadString(csline);app->course.teachers_name.push_back(csline);}
else if(csline=="[VALUE]"){file.ReadString(csline);app->course.courses_credit.push_back(csline);}
}
}
file.Close();
this->SetViews();
}
2.3.10动态添加查询条件:
void CTongji::OnAdd_Conditions()
{
//如果添加的条件数大于7,增加窗口高度
if(cons_size>=7){
CRect rect;
GetWindowRect(&rect);
rect.BottomRight().y+=25;
SetWindowPos(NULL,0,0,rect.Width(),rect.Height(),
SWP_NOMOVE | SWP_NOZORDER);
}
CSJ4App *app=(CSJ4App*)AfxGetApp();
int j;
CString s;
int courses_size=app->course.courses_name.size();
CComboBox *sub_box=new CComboBox;
CStatic *st=new CStatic[courses_size];
//创建逻辑选择条件列表,其ID设置为666+cons_size sub_box->Create(WS_CHILD|WS_VISIBLE|WS_VSCROLL|CBS_DROPDOWNLIST,CRect(20,80+(cons_size-1)*25,90,170+(cons_size-1)*25), this, cons_size+666);
sub_box->InsertString(0,"并且");
sub_box->InsertString(1,"或者");
sub_box->InsertString(2,"非");
sub_box->SetCurSel(0);
CComboBox *subs=new CComboBox;
//创建课程名称表,其ID设置为777+cons_size subs->Create(WS_CHILD|WS_VISIBLE|WS_VSCROLL|CBS_DROPDOWNLIST,CRect(95,80+(cons_size-1)*25,210,170+(cons_size-1)*25), this, cons_size+777);
for(j=0;j<courses_size;j++)
{
subs->InsertString(j,app->course.courses_name.at(j));
}
CComboBox *con_box=new CComboBox;
//创建条件选择列表,其ID为888+cons_size con_box->Create(WS_CHILD|WS_VISIBLE|WS_VSCROLL|CBS_DROPDOWNLIST,CRect(280,80+(cons_size-1)*25,330,170+(cons_size-1)*25), this, cons_size+888);
con_box->InsertString(0,"小于");
con_box->InsertString(1,"等于");
con_box->InsertString(2,"大于");
CComboBox *score=new CComboBox;
//创建分数选择列表,其ID为111+cons_size score->Create(WS_CHILD|WS_VISIBLE|WS_VSCROLL|CBS_DROPDOWNLIST,CRect(340,80+(cons_size-1)*25,400,170+(cons_size-1)*25), this, cons_size+111);
for(j=0;j<=100;j++)
{
s.Format("%d",j);
score->InsertString(j,s);
}
//最后,条件数加一
cons_size++;
}
2.3.11打印模块:
void CView::OnFilePrint()
{
//打印窗口
CPrintDialog dlg(FALSE);
CDC *dcPrint=GetDC();
if (OnPreparePrinting(&printInfo))
{
if (dlg.DoModal() != IDOK)
return;
}
OnBeginPrinting(dcPrint, &printInfo);
OnPrepareDC(dcPrint, &printInfo);
OnPrint(dcPrint, &printInfo);
OnEndPrinting(dcPrint, &printInfo); // clean up after printing
}
其中加粗的代码行为重载的虚函数,对于 OnPreparePrinting() 函数仅有 return DoPreparePrinting(pInfo);这是在一个打印过程中最先调用的,当然也可以包含一些其它的打印初始化操作,最主要的是要重载三个函数:
OnBeginPrinting();
OnPrint();
OnEndPrinting();
而以 OnPrint 最为复杂,它是写大量代码实现打印功能的地方。对于默认的OnPrint实现是调用CView的OnDraw,也就是和绘制视图类的客户区的内容完全相同的方法来在打印机上绘图。实际中我们在两种地方绘图的内容是完全不同的,可能用户在客户区绘的是一个曲线,而在打印机上要绘制表格和数据。OnPrint(CDC* pDC, CPrintInfo* pInfo)的第二个参数是一个CPrintInfo类型的指针,可以从这个指针指向的对象中获得信息,如总共的页数,当前的页数.
2.3.12 计算加权以及排序模块:
void CSJ4View::OnSort()
{
CSJ4App *app=(CSJ4App*)AfxGetApp();
app->avg.clear();
app->sort_result.clear();
int stu_size=app->stu_scores_link.size();
int subs_size=app->course.courses_credit.size();
int i;
int cred_sum=0;
//学分总和
for(int j=0;j<subs_size;j++)
cred_sum=cred_sum+atoi(app->course.courses_credit.at(j));
for(i=0;i<stu_size;i++)
{
int sum=0;
//计算总分
for(j=0;j<subs_size;j++){
sum=sum+atoi(app->course.courses_credit.at(j))*atoi(app->stu_scores_link.at(i).subs_scores.at(j));
}
double aver=(double)sum/cred_sum;
app->avg.push_back(aver);
}
vector<int> tt;
for(i=0;i<stu_size;i++)
{
tt.push_back(1);}
int id;
double max;
//排序结果存于sort_result
for(i=0;i<stu_size;i++)
{
max=-1;
for(j=0;j<stu_size;j++)
if(tt.at(j)==1&&app->avg.at(j)>=max){max=app->avg.at(j);
id=j;
}
app->sort_result.push_back(id);
tt.at(id)=0;
}
app->flush_sort();
}
2.3.13 添加与修改课程
2.3.14 重绘所有表格
详细代码见附2
3,参考文献
[1]MSDN Library Visual Studion 6.0
[2]<Visual C++ 6.0技术内幕>>,机械工业出版社
[3]Visual C++ 从入门到精通[M].电子工业出版社
附1:
从向量second_query中查询,得到结果返回
Vector<int> CTongji::get_query_result_from(vector<int> second_query);
{
//获取控件
CComboBox *sub_name=(CComboBox * )GetDlgItem(IDC_SUBNAME);
CComboBox *con=(CComboBox * )GetDlgItem(IDC_CONDITION);
//获取选中项
int sel=sub_name->GetCurSel();
int consel=con->GetCurSel();
CString sstr;
GetDlgItemText(IDC_SCORES,sstr);
int scoresel=atoi(sstr);
CString constr,scorestr,temp;
GetDlgItemText(IDC_CONDITION,constr);
GetDlgItemText(IDC_SCORES,scorestr);
int v;
//清空原有的查询结果列表
second_query.clear();
int stu_size= second_query.size();
//consel=0表示”小于”1表示”等于”,2表示”大于”
for(int i=0;i<stu_size;i++){
if(consel==0){
//CString 转int
v=atoi(app->stu_scores_link.at(second_query.at(i)).subs_scores.at(sel));
if(v<scoresel)
app->query_result_link.push_back(second_query.at(i));
//满足条件后入栈
}
else if(consel==1){
v=atoi(app->stu_scores_link.at(second_query.at(i)).subs_scores.at(sel));
if(v==scoresel)
app->query_result_link.push_back(second_query.at(i));
}
else {
v=atoi(app->stu_scores_link.at(second_query.at(i)).subs_scores.at(sel));
if(v>scoresel)
app->query_result_link.push_back(second_query.at(i));}
}
Return app->query_result_link;
}
void CTongji::Query()
{
CSJ4App *app=(CSJ4App*)AfxGetApp();
//第一次查询
Vector<int> second_query=get_query_result_from(app->stu_scores_link);
//开始多条件处理
for(int j=1;j<cons_size;j++)
{
//条件信息获取
CComboBox *a=(CComboBox * )GetDlgItem(666+j);
CComboBox *b=(CComboBox * )GetDlgItem(777+j);
CComboBox *c=(CComboBox * )GetDlgItem(888+j);
GetDlgItemText(111+j,sstr);
int andornot=a->GetCurSel();
int subsel=b->GetCurSel();
int compare=c->GetCurSel();
int selscore=atoi(sstr);
CString tt;
int k;
vector<int> second_query=app->query_result_link;
//andornot表示逻辑,0表示”并且”,1表示”或者”,2表示”非”
if(andornot==0){
app->query_result_link.clear();
int sec_size=second_query.size();
for(k=0;k<sec_size;k++)
{
if(compare==0){
v=atoi(app->stu_scores_link.at(second_query.at(k)).subs_scores.at(subsel));
CString t;
if(v<selscore)app->query_result_link.push_back(second_query.at(k));
}
else if(compare==1){
v=atoi(app->stu_scores_link.at(second_query.at(k)).subs_scores.at(subsel));
CString t;
t.Format("%d",v);
if(v==selscore)app->query_result_link.push_back(second_query.at(k));
}
else {
v=atoi(app->stu_scores_link.at(second_query.at(k)).subs_scores.at(subsel));
if(v>selscore)app->query_result_link.push_back(second_query.at(k));
}
}
}
else if(andornot==1){
int sec_size=second_query.size();
//开辟空间
int *temp=new int[sec_size];
for(k=0;k<sec_size;k++)
{
*(temp+k)=second_query.at(k);
}
for(k=0;k<app->stu_scores_link.size();k++)
{
if(compare==0){
v=atoi(app->stu_scores_link.at(k).subs_scores.at(subsel));
CString t;
//判断是否已在查询列表中 if(v<selscore&&!Isexist(k,temp,sec_size))app->query_result_link.push_back(k);
}
else if(compare==1){
v=atoi(app->stu_scores_link.at(k).subs_scores.at(subsel));
CString t;
if(v==selscore&&!Isexist(k,temp,sec_size))app->query_result_link.push_back(k);
}
else{
v=atoi(app->stu_scores_link.at(k).subs_scores.at(subsel));
if(v>selscore&&!Isexist(k,temp,sec_size))app->query_result_link.push_back(k);
}
}
delete temp;
}
else {
int sec_size=second_query.size();
vector<int> temp;
for(k=0;k<sec_size;k++)
{
if(compare==0){
v=atoi(app->stu_scores_link.at(second_query.at(k)).subs_scores.at(subsel));
CString t; if(v<selscore)temp.push_back(second_query.at(k));
}
else if(compare==1){
v=atoi(app->stu_scores_link.at(second_query.at(k)).subs_scores.at(subsel));
CString t;
if(v==selscore)temp.push_back(second_query.at(k)); }
else {
v=atoi(app->stu_scores_link.at(second_query.at(k)).subs_scores.at(subsel));
if(v>selscore)temp.push_back(second_query.at(k)); }
}
int temp_size=temp.size();
int *temp2=new int[temp_size];
for(k=0;k<temp_size;k++)
*(temp2+k)=temp.at(k);
app->query_result_link.clear();
for(k=0;k<sec_size;k++)
if(!Isexist(second_query.at(k),temp2,temp_size))
app->query_result_link.push_back(second_query.at(k));
delete temp2;
}
delete a,b,c;
}
//重绘FlexGrid
app->flush_query();
if(notclose==1)CDialog::OnOK();
}
附录2:
//刷新成绩表与课程信息表
void CSJ4App::flush()
{
extern CString str;
CMainFrame* pMain=(CMainFrame*)AfxGetMainWnd();
CSJ4View* vv =(CSJ4View*) pMain->GetActiveView();
vv->m_fgrid.Clear();
vv->m_cgrid.Clear();
if(vv->m_fgrid.GetRows()<=stu_scores_link.size())
vv->m_fgrid.SetRows(stu_scores_link.size()+1);
vv->InitGrid();
vv->m_fgrid.SetCols(3+this->subs_size);
int temp;
CString male;
vv->m_fgrid.SetBackColor(RGB(221,242,215));
for(i=0;i<this->stu_scores_link.size();i++)
{
temp=0;
vv->m_fgrid.SetTextMatrix(i+1,temp++,this->stu_scores_link.at(i).id);
vv->m_fgrid.SetTextMatrix(i+1,temp++,this->stu_scores_link.at(i).name);
male=(this->stu_scores_link.at(i).male==0)?"男":"女";
vv->m_fgrid.SetTextMatrix(i+1,temp++,male);
for(j=0;j<this->course.courses_name.size();j++)
{
vv->m_fgrid.SetTextMatrix(i+1,temp++,this->stu_scores_link.at(i).subs_scores.at(j));
}
}
vv->m_fgrid.SetCols(3+course.courses_name.size());
vv->m_cgrid.SetBackColor(RGB(221,242,215));
for(i=0;i<this->course.courses_credit.size();i++)
{
temp=0;
for(j=0;j<course.courses_name.size();j++)
vv->m_fgrid.SetTextMatrix(0,j+3,course.courses_name.at(j));
vv->m_cgrid.SetTextMatrix(i+1,temp++,course.courses_name.at(i));
vv->m_cgrid.SetTextMatrix(i+1,temp++,course.courses_credit.at(i));
vv->m_cgrid.SetTextMatrix(i+1,temp++,course.teachers_name.at(i));
}
}