Search code examples
reporting-servicesrdlcssrs-tablixrdl

Horizontal and custom table in rdlc report


This is my database(Dataset)."Main Process" can separate to to many "Sub Process".

Example : A is main process.It's have three sub process.(a1,a2 and a3)

  ----Main Process---|----SUB_PROCESS---|
          A          |        a1
          A          |        a2
          A          |        a3
          B          |        b1
          B          |        b2
          B          |        b3
          B          |        b4
          B          |        b5
          C          |        c1
          C          |        c2

Report will binding with above Dataset. Below figure is my report layout.

enter image description here

  • Horizontal Tablix (Change row to column)
  • If Main Process has "sub process" more than 3 elements. Next record must skip for write sub process elements.

Help me please , It's so difficult. Is it possible?


Solution

  • This is a real tough one, I don't really think there is an easy way to solve this. I would solve this by creating a new datasource in which you group everything nicely.

    It's really hard to make this happen dynamically. But below is an example of how I would handle this for your example. There are a fixed number of rows (in your case 4) so I create new lists for each row and fill them dynamically, filling the empty spots with empty strings on the fly. This way the table will grow horizontally and keep 4 rows.

    var row1 = new List<string>();
    var row2 = new List<string>();
    var row3 = new List<string>();
    var row4 = new List<string>();
    var rowHeaders = new List<string>();
    
    myDataList.OrderBy(p => p.MainProcess).ThenBy(p => p.SubProcess);
    foreach (var proc in myDataList)
    {
        if (!rowHeaders.Contains(proc.MainProcess))
        {
            row1.Add(proc.MainProcess);
            rowHeaders.Add(proc.MainProcess);
            if (row2.Count == row1.Count - 2)
                row2.Add("");
            if (row3.Count == row1.Count - 2)
                row3.Add("");
            if (row4.Count == row1.Count - 2)
                row4.Add("");
            row2.Add(proc.SubProcess);
        }
        else
        {
            if (row2.Count == row1.Count - 1)
            {
                row2.Add(proc.SubProcess);
            }
            else
            {
                if (row3.Count == row2.Count - 1)
                {
                    row3.Add(proc.SubProcess);
                }
                else
                {
                    if (row4.Count == row3.Count - 1)
                    {
                        row4.Add(proc.SubProcess);
                    }
                    else
                    {
                        row1.Add(proc.SubProcess);
                    }
                }
            }
        }
    }
    
    
    if(row2.Count < row1.Count)
        row2.Add("");
    if (row3.Count < row2.Count)
        row3.Add("");
    if (row4.Count < row3.Count)
        row4.Add("");
    
    var myDataSource = new List<List<string>>();
    myDataSource.Add(row1);
    myDataSource.Add(row2);
    myDataSource.Add(row3);
    myDataSource.Add(row4);
    

    There are probably more clean ways to filter your data, but this will definitely do the trick. To get your Main Process in bold text you could add the "rowHeader" list as a parameter and use Expressions.

    I hope this is of any help to you and if someone knows how to clean up my code, please feel free to edit.