C#中DataTable行转列示例

将下面表(1)格式的数据转换为表(2)格式的数据。很明显,这是一个行转列的要求,本想在数据库中行转列,因为在数据库中行转列是比较简单的,方法可以参考本站SQLServer中(行列转换)行转列及列转行且加平均值及汇总值,但因其它需求,最终需将该转化搬到C#中进行了。

(表1)

 

表(2)

 

不多说了,下面开始在DataTable行转列示例:

 

//DataTable行转列

private DataTable RCC(DataTable _outDataSource)

{

    //从DataTable中读取不重复的日期行,用来构造新DataTable的列

    DataTable distinct_date = _outDataSource.DefaultView.ToTable(true, "日期");

 

    DataTable new_DataTable = new DataTable();

 

    //将客户名称列添加到新表中

    DataColumn new_d_col = new DataColumn();

    new_d_col.ColumnName = "客户名称";

    new_d_col.Caption = "";

    new_DataTable.Columns.Add(new_d_col);

 

    StringBuilder str_sum = new StringBuilder();

 

    //开始在新表中构造日期列

    foreach (DataRow dr in distinct_date.Rows)

    {

        new_d_col = new DataColumn();

        new_d_col.DataType = typeof(decimal);

        new_d_col.ColumnName = dr["日期"].ToString();

        new_d_col.Caption = dr["日期"].ToString();

        new_d_col.DefaultValue = 0;

        new_DataTable.Columns.Add(new_d_col);

 

        //这个的目的是为合计列构造expression

        str_sum.Append("+[").Append("日期").Append("]");

    }

 

    //将合计列添加到新表中

    new_d_col = new DataColumn();

    new_d_col.DataType = typeof(decimal);

    new_d_col.ColumnName = "Sum";

    new_d_col.Caption = "合计";

    new_d_col.DefaultValue = 0;

    new_d_col.Expression = str_sum.ToString().substring(1);

    new_DataTable.Columns.Add(new_d_col);

 

    /*好了,到此新表已经构建完毕,下面开始为新表添加数据*/

 

    //从原DataTable中读出不重复的客户名称,以客户名称为关键字来构造新表的行

    DataTable distinct_object = _outDataSource.DefaultView.ToTable(true, "客户名称");

    DataRow[] drs;

    DataRow new_dr;

    foreach (DataRow dr in distinct_object.Rows)

    {

        new_dr = new_DataTable.NewRow();

        new_dr["客户名称"] = dr["客户名称"].ToString();

 

        foreach (DataRow _dr in distinct_date.Rows)

        {

            drs = _outDataSource.Select("客户名称='" + dr["客户名称"].ToString() + "' and 日期='" + _dr["日期"].ToString() + "'");

            if (drs.Length != 0)

            {

                new_dr[_dr["日期"].ToString()] = Math.Round(Convert.ToDecimal(drs[0]["金额"]), 2);

            }

        }

        new_DataTable.Rows.Add(new_dr);

    }

     return new_DataTable;

}

 

从上面的代码中看到我们并没有为新表"合计"这一列赋值,这是因为该列具有表达式str_sum.Append("+[").Append("日期").Append("]"),所以这列的值是会自动填充的。

 

注意,在上面的表达式中,我们加了[],在DataTable的表达式中,如果列名是中文,一定要为列名加上[],要不然会报错的,这也是我调试了好久才发现的。

public DataTable RowsToCol(DataTable DT)
{
       try
        {  
                      int  rowCount=DT.Rows.Count;
                      int  columnsCount=DT.Columns.Count;
                      DataTable result=new DataTable();
                      DataTable RowsDT=new DataTable();
                      DataTable COLSDT=new DataTable();
                      for(int i=0;i<RowCount;i++)
                      {
                              result.Columns.Add(DT.Rows[i][1].ToString());
                              RowsDT.Columns.Add(DT.Rows[i][1].ToString());
                              COLsDT.Columns.Add(DT.Rows[i][1].ToString());
                      }
                      string[] RowsName=new string[columnsCount];
                      for(int i=0;i<columnsCount;i++)
                      {                           
                      RowsName[i]=DT.Columns[i].ColumnName.Tostring();
                      }
                      for(int rowsi=0;rowsi<RowsName.Length;rowsi)
                      {
                      RowsDT.Rows.Add(new string[] {RowsName[rowsi]});
                      }
                      //行转列的核心部分
                      for(int columnsi=0;columnsi<columnsCount;columnsi++)
                      {
                           DataRow dr=COLsDT.NewRow();
                           for(int rowj=0;rowj<rowCount;rowj++)
                           {
                                  dr[rowj]=DT.Rows[rowj][columnsi].toString();
                           }
                           COLsDT.Rows.Add(dr);
                      }
                      
             for(int columnsi=0;columnsi<columnsCount;columnsi++)
             {
                 DataRow resultdr=result.NewRow();
                 for(int rowj=0;rowj<rowCount;rowj++)
                 {
                    if(rowj==0)
                     {
                       resultdr[rowj]=RowsDT.Rows[columnsi][0].ToString();
                     }
                     else
                     {
                      resultdr[rowj]=ColsDT.Rows[columnsi][rowj].ToString();
                      }
                  }
                 result.Rows.Add(resultdr);
            }
            
            return   result;
       }
       catch(Exception ex)
       {
            throw new Exception(ex.ToString());
       }
}

要转的DataTable结构如下图:


privateDataTableConvertDataTable(DataTable dtSrc)

{

try

{

DataTable dt =newDataTable();

dt.Columns.Add("姓名");

varcolumns = (frompindtSrc.Rows.Cast<DataRow>()selectp[1].ToString()).Distinct();

foreach(varitemincolumns) dt.Columns.Add(item);

vardata =fromkinsource.Rows.Cast<DataRow>()

groupkbyk[0]intom

selectnew{ Key = m.Key.ToString(), Items = m };

data.ToList().ForEach(n =>

{

string[] array =newstring[dt.Columns.Count];

array[0] = n.Key;

for(inti =1; i < dt.Columns.Count; i++)

array[i] = (frompinn.Items

wherep[1].ToString() == dt.Columns[i].ToString()

selectp[2].ToString())

.SingleOrDefault();

dt.Rows.Add(array);

});

returndt;

}

catch

{

returnnull;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值