DataTable某列的值转换成行,返回交叉二维表

来源:互联网 发布:大数据时代要学什么 编辑:程序博客网 时间:2024/05/17 23:35


private void BtnGetReport_Click(System.Object sender, System.EventArgs e){DataTable Dt = GetCrossTable(CreateDT(), "ID", "Type", "Score");Dgv.DataSource = Dt;}/// <summary>/// 创建DataTable/// </summary>/// <returns></returns>/// <remarks></remarks>protected DataTable CreateDT(){DataTable tblDatas = new DataTable("Datas");//数据列tblDatas.Columns.Add("ID", Type.GetType("System.String"));tblDatas.Columns.Add("Name", Type.GetType("System.String"));tblDatas.Columns.Add("Type", Type.GetType("System.String"));tblDatas.Columns.Add("Score", Type.GetType("System.Int32"));//数据行tblDatas.Rows.Add(new object[] {"00001","张三","语文",89});tblDatas.Rows.Add(new object[] {"00001","张三","数学",90});tblDatas.Rows.Add(new object[] {"00001","张三","英语",79});tblDatas.Rows.Add(new object[] {"00001","张三","地理",70});tblDatas.Rows.Add(new object[] {"00001","张三","生物",95});tblDatas.Rows.Add(new object[] {"00002","李四","语文",87});tblDatas.Rows.Add(new object[] {"00002","李四","英语",86});tblDatas.Rows.Add(new object[] {"00002","李四","地理",82});tblDatas.Rows.Add(new object[] {"00003","王五","语文",81});tblDatas.Rows.Add(new object[] {"00003","王五","数学",70});tblDatas.Rows.Add(new object[] {"00003","王五","英语",88});tblDatas.Rows.Add(new object[] {"00003","王五","生物",96});return tblDatas;}/// <summary>/// 将DataTable某列的值转换成行,返回交叉二维表/// 注意:源表数据必须已按唯一值的列排序/// </summary>/// <param name="Dt">源表</param>/// <param name="OnlyColumn">源表多行判断唯一值的列名</param>/// <param name="CvrtColumn">源表需行转列的列名</param>/// <param name="ValueColumn">源表的数据值列名,此列必须为数值</param>/// <returns></returns>/// <remarks></remarks>public static DataTable GetCrossTable(DataTable Dt, string OnlyColumn, string CvrtColumn, string ValueColumn){if (Dt == null || Dt.Columns.Count < 3 || Dt.Rows.Count == 0) {return Dt;} else {//1.定义List,并赋值非转换列和值列的名称ArrayList ColumnList = new ArrayList();for (int i = 0; i <= Dt.Columns.Count - 1; i++) {if (Dt.Columns[i].ColumnName.ToString() != CvrtColumn & Dt.Columns[i].ColumnName.ToString() != ValueColumn) {ColumnList.Add(Dt.Columns[i].ColumnName.ToString());}}//2.定义返回表,将非转换的列和具体值列,添加至表DataTable ReDt = new DataTable();for (int i = 0; i <= ColumnList.Count - 1; i++) {ReDt.Columns.Add(ColumnList[i].ToString());}//2.将转换列的行不重复记录生成新表DataTable dtColumns = Dt.DefaultView.ToTable("dtColumns", true, CvrtColumn);//3.将转换列的行的值,生成返回表的列for (int i = 0; i <= dtColumns.Rows.Count - 1; i++) {string colName = null;if (dtColumns.Rows[i][0] is DateTime) {colName = Convert.ToDateTime(dtColumns.Rows[i][0]).ToString().Trim();} else {colName = dtColumns.Rows[i][0].ToString().Trim();}ReDt.Columns.Add(colName);ReDt.Columns[ReDt.Columns.Count - 1].DefaultValue = "0";}//4.定义DataRow为返回表的NewRowDataRow drNew = ReDt.NewRow();//5.将除转换行的列和值列之外的列,赋值上源表第一行的值for (int i = 0; i <= ColumnList.Count - 1; i++) {drNew[ColumnList[i].ToString()] = Dt.Rows[0][ColumnList[i].ToString()];}//数据唯一值,赋值为源表第一行唯一值string OnlyRow = drNew[OnlyColumn].ToString();//循环源表,判断赋值foreach (DataRow dr in Dt.Rows) {//转换的行的值(新表列名)string colName = dr[CvrtColumn].ToString().Trim();//数值行的值double dValue = Convert.ToDouble(dr[ValueColumn]);//新表新行的唯一值和源表对比if (dr[OnlyColumn].ToString().Equals(OnlyRow, StringComparison.CurrentCultureIgnoreCase)) {//相同,则新表新行的列(转换行)赋值drNew[colName] = dValue.ToString();} else {//不相同,则新表新增一行ReDt.Rows.Add(drNew);drNew = ReDt.NewRow();//并赋值源表当前行的非转行行和值行的数据for (int i = 0; i <= ColumnList.Count - 1; i++) {drNew[ColumnList[i].ToString()] = dr[ColumnList[i].ToString()];}//数据唯一值, 赋值为源表当前行的唯一值OnlyRow = drNew[OnlyColumn].ToString();drNew[colName] = dValue.ToString();}}ReDt.Rows.Add(drNew);return ReDt;}}


0 0