C1Reports have not just made reporting easy; the customizations and features it offers have also added it in the list of user-friendly controls.

Generally, the reports are designed in the designer and then either the complete data is shown or the filtered records are fetched on the basis of the parameters passed by the users. What if the designing of the reports could also be done as per the user's discretion? That is, the users can decide which field to add in the report and which one to leave out.

This blog deals with the implementation of the same.

In order to allow the user to choose the fields that are to be added in the report, please note the following:

  1. The report should be created at runtime.

  2. The list of all the columns present in the data source of the report should be available at the time of report designing.


In our implementation we have used a couple of reports bound to different data sources. When the user selects any report the list of columns from the data source is shown in the listbox. The user can select which fields he wants to render on the report and add them in the second listbox.

Now, when the choices have been made, the selected columns are queried using the SQL query and set as the RecordSource of the report. The following is the code that is used to create the desired report:

 C1Report1.DataSource.RecordSource = ""
Dim field_count As Integer = C1Report1.Fields.Count
For c = 0 To field_count - 1
C1Report1.Fields.RemoveAt(c)
Next
Dim col As String = ""
Dim items = (From i In ListBox2.Items).ToArray()

'Get the list of all selected columns
For i = 0 To ListBox2.Items.Count - 1
If ListBox2.Items.Count > 1 Then
If i < ListBox2.Items.Count - 1 Then
col = col & items(i).ToString & " , "
Else
col = col & items(i).ToString
End If
Else
col = items(i).ToString
End If
Next

'Setting the recordsource on the basis of the selected column names
C1Report1.DataSource.RecordSource = "select " & col & " from " & dt.TableName

C1Report1.Layout.Orientation = OrientationEnum.Portrait

Dim f As Field
With C1Report1.Sections(SectionTypeEnum.Header)
.Height = 1440
.Visible = True
.BackColor = Color.FromArgb(200, 200, 200)
f = .Fields.Add("FldTitle", "New Report", 0, 0, 8000, 1440)
f.Font.Size = 24
f.Font.Bold = True
f.ForeColor = Color.FromArgb(0, 0, 100)
End With

l = 0
With C1Report1.Sections(SectionTypeEnum.PageHeader)
.Height = 300
.Visible = True
.CanGrow = False
C1Report1.Font.Bold = True

For i As Integer = 0 To ListBox2.Items.Count - 1
If i = 0 Then
f = .Fields.Add(ListBox2.Items(i).ToString, ListBox2.Items(i).ToString, 0, t, w, h)
Else
l = l + 1500
f = .Fields.Add(ListBox2.Items(i).ToString, ListBox2.Items(i).ToString, l, t, w, h)
End If
f.Align = FieldAlignEnum.CenterMiddle
f.CanGrow = True
Next
End With

l = 0
With C1Report1.Sections(SectionTypeEnum.Detail)
.Height = 300
.Visible = True
.CanGrow = True
C1Report1.Font.Bold = False

For i As Integer = 0 To ListBox2.Items.Count - 1
If i = 0 Then
f = .Fields.Add("D" & ListBox2.Items(i).ToString, ListBox2.Items(i).ToString, 0, t, w, h)
Else
l = l + 1500
f = .Fields.Add("D" & ListBox2.Items(i).ToString, ListBox2.Items(i).ToString, l, t, w, h)
End If
f.Align = FieldAlignEnum.CenterMiddle
f.Calculated = True
f.CanGrow = True
Next

End With
C1PrintPreviewControl1.Document = C1Report1


Please refer to the attached Sample for the detailed implementation.

The following are the two outputs generated on the basis of the different fields selected by the user for the same report:

A. Shows the fields: ProductID, ProductName, CategoryID



B. Shows the fields: ProductId, QuantityPerUnit, UnitPrice, UnitsInStock