this.lbFiles.Items.Clear();
int FileCount = 0;
FileInfo[] infoArray1 = new DirectoryInfo(FilePath).GetFiles();
foreach (FileInfo info2 in infoArray1)
{
if ( info2.Extension.ToUpper()==".DBF" )
{ // 只填充DBF文件并统计个数
this.lbFiles.Items.Add(info2.Name.Trim());
FileCount++;
}
}
label2.Text="数据文件列表:("+FileCount+"个文件)";
}
catch (Exception exception1)
{
MessageBox.Show(exception1.Message);
}
if (FilePath != "")
Browser(FilePath); // 浏览考生数据
}
3.获取高招导出数据表关联的考生信息
通过Browser()方法获取高招导出数据表关联的考生信息。根据对高招导出数据表的结构分析可知:
(1)考生信息数据主要存放在图1所示的DBF相关表中。通过连接查询并加载连接字段条件将多个表连接起来,从而实现从多个表中检索出所需要的数据。
(2)由于T_TDD.DBF表中多数为代码字段,代码字段的真实含义字段在另一个代码表中;这样,就必须以T_TDD.DBF表的每行数据去匹配代码表的数据列,符合连接条件的数据直接返回到结果集中。对那些不符合连接条件的列将被填上NULL值后再返回到结果集中(不同省(市、自治区)对考生基本信息的采集方式并不一致,有的省(市、自治区)对考生的某些信息字段并没有录入,这样,相应的代码字段为空)。
如果将T_TDD.DBF作为主表放在连接条件的左边,那么,使用SQL Server的Left Outer Join(左外部连接)查询即可获取考生的全部有用信息。(对T_TDD.DBF表不加限制,而只限制相应的代码表)
(3)获取的考生基本信息存放在DataSet对象的DataTable对象中。
DataSet是ADO.NET结构的主要组件,它是从数据源中检索到的数据在内存中的缓存。DataSet对象可以存储数据库中信息的拷贝,可以在切断数据库连接时处理这个本地拷贝。DataSet是一般性的适用于任何数据库。DataSet还可以按任何顺序读行和修改行。可以在DataSet中修改这个本地拷贝,然后通过DataAdapter对象在数据集和数据库之间同步记录。
DataSet是包含表和这些表之间关系的集合。每个表包含一个列集合。这些对象代表了数据集的模式。每个表都有多个行,表示这个数据集所保持的数据。这些行记得它们的初始状态和当前状态,以便数据集可以跟踪发生了何种改变。
DataSet中可以存储多个DataTable对象。DataTable表示内存中数据的一个表,核心代码如下:
private void Browser(string FilePath)
{ // 获取考生信息
if (FilePath == "") return;
this.m_Conns.ConnectionString = "Provider=VFPOLEDB.1;Collating Sequence=MACHINE;Data Source=" + FilePath;
try
{
this.Cursor = Cursors.WaitCursor;
this.m_Ds.Clear();
this.m_Conns.Open();
// 获取考生基本信息
string sql = "SELECT T_TDD.KSH, T_TDD.XM, T_TDD.CSNY, T_TDD.XBDM, TD_XBDM.XBMC, T_TDD.MZDM, TD_MZDM.MZMC, TD_ZZMMDM.ZZMMMC, T_TDD.TJJLDM, TD_TJJLDM.TJJLMC, T_TDD.SFZH, T_TDD.ZXMC, T_TDD.WYYZDM, TD_WYYZDM.WYYZMC, TD_KSLBDM.KSLBMC, TD_DQDM.DQDM, TD_DQDM.DQMC, T_TDD.JTDZ, T_TDD.YZBM, T_TDD.LXDH, T_TDD.CJ, T_TDD.LQZY, T_JHK.ZYDM, T_JHK.ZYMC, T_TDD.PCDM, TD_PCDM.PCMC, T_TDD.KLDM, TD_KLDM.KLMC, T_TDD.KSTZ, TD_ZCDM.ZCMC, T_TDD.ZYZYTJ, T_TDD.BZ FROM T_TDD LEFT OUTER JOIN T_JHK ON T_TDD.PCDM = T_JHK.PCDM AND T_TDD.LQZY = T_JHK.ZYDH AND T_TDD.KLDM = T_JHK.KLDM LEFT OUTER JOIN TD_XBDM ON T_TDD.XBDM = TD_XBDM.XBDM LEFT OUTER JOIN TD_MZDM ON T_TDD.MZDM = TD_MZDM.MZDM LEFT OUTER JOIN TD_ZZMMDM ON T_TDD.ZZMMDM = TD_ZZMMDM.ZZMMDM LEFT OUTER JOIN TD_TJJLDM ON T_TDD.TJJLDM = TD_TJJLDM.TJJLDM LEFT OUTER JOIN TD_WYYZDM ON T_TDD.WYYZDM = TD_WYYZDM.WYYZDM LEFT OUTER JOIN TD_DQDM ON T_TDD.DQDM = TD_DQDM.DQDM LEFT OUTER JOIN TD_PCDM ON T_TDD.PCDM = TD_PCDM.PCDM LEFT OUTER JOIN TD_KLDM ON T_TDD.KLDM = TD_KLDM.KLDM LEFT OUTER JOIN TD_ZCDM ON T_TDD.KSTZ = TD_ZCDM.ZCDM LEFT OUTER JOIN TD_KSLBDM ON T_TDD.KSLBDM = TD_KSLBDM.KSLBDM";
OleDbCommand cmd = new OleDbCommand(sql,m_Conns);//
new OleDbDataAdapter(cmd).Fill(m_Ds, "KsInfo");
if (this.m_Ds.Tables["KsInfo"].Rows.Count < 1 )
return; // 无考生,返回
this.dataGrid1.DataSource = m_Ds.Tables["KsInfo"];
// 获取生源地所在省(市、自治区)代码ProvinceID及名称ProvinceName
DataView dv = new DataView(this.m_Provinces);
DataTable dt = this.m_Ds.Tables["KsInfo"];
string KSH=dt.Rows[0]["KSH"].ToString().Trim();//考生号
string ProvinceID = KSH.Substring(2, 2);
string ProvinceName = "";
if (KSH.Length ==14)
{
dv.RowFilter = "Code = " + ProvinceID;
if (dv.Count > 0)
ProvinceName = dv[0]["CodeMean"].ToString().Trim();
this.cbProvinces.SelectedValue = ProvinceID;
this.cbProvinces.Enabled = false;
}
else
{
MessageBox.Show("无法获取生源地所在省(市、自治区),请手工选择!","操作提示");
this.cbProvinces.Enabled = true;
}
this.cbProvinces.Visible = true;
// 获取考生简历
OleDbCommand cmd1 = new OleDbCommand("SELECT * FROM T_KSJL", this.m_Conns);
new OleDbDataAdapter(cmd1).Fill(m_Ds, "T_KSJL");
// 创建 KsInfo 和 T_KSJL 的父/子表关系
this.m_Ds.Relations.Clear();//清除集合中的所有关系
DataTable parentTable= m_Ds.Tables["KsInfo"];
DataTable childTable = m_Ds.Tables["T_KSJL"];
DataColumn parentCol = parentTable.Columns["KSH"];
DataColumn childCol = childTable.Columns["KSH"];
DataRelation relOrder = new DataRelation("简历", parentCol, childCol);
m_Ds.Relations.Add(relOrder);
this.dataGrid1.CaptionText = "考生基本信息";
this.dataGrid1.DataSource = parentTable;
this.dataGrid1.AllowNavigation = true;
}
catch (Exception exception1)
{
MessageBox.Show(exception1.Message);
return;
}
finally
{
this.m_Conns.Close();
this.statusBar1.Text = "记录数:" + this.m_Ds.Tables["KsInfo"].Rows.Count;
this.btnOK.Enabled = true; // 使能“导入”按钮
this.Cursor = Cursors.Default;
}
}
4.将获取的考生信息导入到新生数据表中
为保证数据一致性,避免重复导入,一般采用存储过程或数据集更新模式完成。但由于存储过程方式对浮点型数据(如本例的成绩)处理不够理想,所以,本程序使用了数据集更新模式。
同时,采用数据集更新模式要求数据表中必须有标识列,否则,会出现“对于不返回任何键列信息的SelectCommand不支持DeleteCommand、UpdateCommand的动态SQL生成”错误信息。核心代码如下:
private void btnOK_Click(object sender, System.EventArgs e)
{
this.m_Conna.ConnectionString = conStr;
try
{
this.Cursor = Cursors.WaitCursor;
// 考生基本信息
string sql = "SELECT * FROM NewStudentInfo";
OleDbCommand cmd = new OleDbCommand(sql, m_Conna);
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
OleDbCommandBuilder cb = new OleDbCommandBuilder(da);
da.InsertCommand = cb.GetInsertCommand();
da.DeleteCommand = cb.GetDeleteCommand();
da.UpdateCommand = cb.GetUpdateCommand();
da.Fill(this.m_Ds, "NewStudentInfo");
DataTable table1 = m_Ds.Tables["NewStudentInfo"];
DataView dv1 = new DataView(table1);
//
DataView dv2 = new DataView(this.m_Provinces);
DataTable table2 = this.m_Ds.Tables["KsInfo"];
for (int n = 0; n < table2.Rows.Count; n++)
{
DataRow R = table2.Rows[n];
string KSH = R["KSH"].ToString().Trim();//考生号
string ProvinceID = KSH.Substring(2, 2);
string ProvinceName = "";
if (KSH.Length !=14)
{
ProvinceID = cbProvinces.SelectedValue.ToString();
}
dv2.RowFilter = "Code = " + ProvinceID;
if (dv2.Count > 0)
ProvinceName = dv2[0]["CodeMean"].ToString().Trim();
dv1.RowFilter = "ExamineNo=" + KSH;
DataRow r;
if (dv1.Count > 0) //该记录已存在
r = dv1[0].Row; //
else
r = table1.NewRow();
r["ExamineNo"] = KSH;
r["Hometown"] = ProvinceName;
r["SID"] = R["SFZH"].ToString().ToUpper();
r["StudentName"] = R["XM"];
r["Sex"] = R["XBMC"];
// …其他同上行格式(略)
r["IsCheckIn"] = false; // 未报到
if (dv1.Count <= 0) //该记录不存在
table1.Rows.Add(r);
} // end of for n
da.Update(table1); // 更新考生基本信息
this.dataGrid1.DataSource = table1;
// 考生简历
sql = "SELECT * FROM NewStudentIntro";
cmd = new OleDbCommand(sql, this.m_Conna);
da = new OleDbDataAdapter(cmd);
cb = new OleDbCommandBuilder(da);
da.InsertCommand = cb.GetInsertCommand();
da.Fill(this.m_Ds, "NewStudentIntro");
table1 = this.m_Ds.Tables["NewStudentIntro"];
DataView dv3 = new DataView(table1);
table2 = m_Ds.Tables["T_KSJL"]; // 新的考生简历
for (int n = 0; n < table2.Rows.Count; n++)
{
DataRow R = table2.Rows[n];
dv3.RowFilter = "ExamineNo='" + R["ksh"] + "' AND BeginDate='" + R["qsrq"] + "' AND EndDate='" + R["zjrq"] + "' AND Company='" + R["jl"] + "'AND HeadShip='" + R["rhzw"] + "' AND Testifier='" + R["zmr"] + "'";
if (dv3.Count > 0) continue;
DataRow r = table1.NewRow(); // 新增一个空行
r["ExamineNo"] = R["ksh"]; // 考生号
r["BeginDate"] = R["qsrq"]; // 开始日期
r["EndDate"] = R["zjrq"]; // 结束日期
r["Company"] = R["jl"]; // 所在单位
r["HeadShip"] = R["rhzw"]; // 职务
r["Testifier"] = R["zmr"]; // 证明人
table1.Rows.Add(r);
}
// 更新考生简历
da.Update(m_Ds.Tables["NewStudentIntro"]);
}
catch (Exception exception1)
{
MessageBox.Show(exception1.Message);
return;
}
finally
{
this.btnOK.Enabled = false; // 禁止“数据导入”
this.Cursor = Cursors.Default;
}
}
五、测试
因为本程序要读取DBF格式的考生信息数据表,所以执行该程序的客户端需要安装Microsoft OLE DB Provider for Visual FoxPro提供程序或安装Visual FoxPro 6.0以上版本。
本程序要求本地或远程安装SQL Server数据库,以便将获取的考生信息写入SQL Server数据库。修改数据库连接串,也可实现写入Access等其他种类数据库。
六、结语
本程序在Visual Studio .NET 2003和MS SQL Server 2000环境下调试通过,在我校新生管理中得到实际应用。对2006年和2007年13个省(市、自治区)的高招录取数据均调试通过。
分专业、分配班级、生成学号、导入学籍管理数据表、新生报到与退档(未报到)处理、新生信息编辑等新生管理部分,不在本文讨论范围内,暂不涉及。
|