C#中DataTable行转列示例


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

客户名称 日期 金额
A客户 1月 1000
B客户 2月 1000
C客户 3月 2000
C客户 4月 2500


表(2)

客户名称 1月 2月 3月 4月 合计
A客户 1000 0 0 0 1000
B客户 0 1000 0 0 1000
C客户 0 0 2000 2500 4500

不多说了,下面开始在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的表达式中,如果列名是中文,一定要为列名加上[],要不然会报错的,这也是我调试了好久才发现的。

 

 

你可能感兴趣的:(Winform,c#,sqlserver,数据库,object,date,c)