Wednesday, 3 July 2013

Dynamic RDLC Reports

One approach I’ve learned just recently in creation of Reports with Dynamic column is by using a Streamed report created programmatically using a RDL Generator class . This will teach you how to create a dynamic column report rdlc using the RDL Generator.
There are three steps to create a Dynamic RDLC reports

Step 1: First is create the RDL Generator Class, this will serve as the creator of the rdl in xml format. write the below code in this Class

Imports System
Imports System.IO
Imports System.Collections.Generic
Imports System.Xml.Serialization

Namespace DynamicTable
    Public Class RdlGenerator
        Private _mAllFields As List(Of String)
        Private _mSelectedFields As List(Of String)
        Private _mSelectedFieldWidths As List(Of String)
        Public Property AllFields() As List(Of String)
            Get
                Return _mAllFields
            End Get
            Set(ByVal value As List(Of String))
                _mAllFields = value
            End Set
        End Property

        Public Property SelectedFields() As List(Of String)
            Get
                Return _mSelectedFields
            End Get
            Set(ByVal value As List(Of String))
                _mSelectedFields = value
            End Set
        End Property
        Public Property SelectedFieldWidths() As List(Of String)
            Get
                Return _mSelectedFieldWidths
            End Get
            Set(ByVal value As List(Of String))
                _mSelectedFieldWidths = value
            End Set
        End Property
        Private Function CreateReport() As Rdl.Report
            Dim report As New Rdl.Report()
            report.Items = New Object() {CreateDataSources(), CreateBody(), CreateDataSets(), "2.5in"}
            report.ItemsElementName = New Rdl.ItemsChoiceType37() {Rdl.ItemsChoiceType37.DataSources, Rdl.ItemsChoiceType37.Body, Rdl.ItemsChoiceType37.DataSets, Rdl.ItemsChoiceType37.Width}
            Return report
        End Function

        Private Function CreateDataSources() As Rdl.DataSourcesType
            Dim dataSources As New Rdl.DataSourcesType()
            dataSources.DataSource = New Rdl.DataSourceType() {CreateDataSource()}
            Return dataSources
        End Function

        Private Function CreateDataSource() As Rdl.DataSourceType
            Dim dataSource As New Rdl.DataSourceType()
            dataSource.Name = "DummyDataSource"
            dataSource.Items = New Object() {CreateConnectionProperties()}
            Return dataSource
        End Function

        Private Function CreateConnectionProperties() As Rdl.ConnectionPropertiesType
            Dim connectionProperties As New Rdl.ConnectionPropertiesType()
            connectionProperties.Items = New Object() {"", "SQL"}
            connectionProperties.ItemsElementName = New Rdl.ItemsChoiceType() {Rdl.ItemsChoiceType.ConnectString, Rdl.ItemsChoiceType.DataProvider}
            Return connectionProperties
        End Function

        Private Function CreateBody() As Rdl.BodyType
            Dim body As New Rdl.BodyType()
            body.Items = New Object() {CreateReportItems(), "0.25in"}
            body.ItemsElementName = New Rdl.ItemsChoiceType30() {Rdl.ItemsChoiceType30.ReportItems, Rdl.ItemsChoiceType30.Height}
            Return body
        End Function

        Private Function CreateReportItems() As Rdl.ReportItemsType
            Dim reportItems As New Rdl.ReportItemsType()
            Dim tableGen As New TableRdlGenerator()
            tableGen.Fields = _mSelectedFields
            tableGen.FieldWidths = _mSelectedFieldWidths
            reportItems.Items = New Object() {tableGen.CreateTable()}
            Return reportItems
        End Function

        Private Function CreateDataSets() As Rdl.DataSetsType
            Dim dataSets As New Rdl.DataSetsType()
            dataSets.DataSet = New Rdl.DataSetType() {CreateDataSet()}
            Return dataSets
        End Function

        Private Function CreateDataSet() As Rdl.DataSetType
            Dim dataSet As New Rdl.DataSetType()
            dataSet.Name = "MyData"
            dataSet.Items = New Object() {CreateQuery(), CreateFields()}
            Return dataSet
        End Function

        Private Function CreateQuery() As Rdl.QueryType
            Dim query As New Rdl.QueryType()
            query.Items = New Object() {"DummyDataSource", ""}
            query.ItemsElementName = New Rdl.ItemsChoiceType2() {Rdl.ItemsChoiceType2.DataSourceName, Rdl.ItemsChoiceType2.CommandText}
            Return query
        End Function

        Private Function CreateFields() As Rdl.FieldsType
            Dim fields As New Rdl.FieldsType()

            fields.Field = New Rdl.FieldType(_mAllFields.Count - 1) {}
            For i As Integer = 0 To _mAllFields.Count - 1
                fields.Field(i) = CreateField(_mAllFields(i))
            Next

            Return fields
        End Function

        Private Function CreateField(ByVal fieldName As [String]) As Rdl.FieldType
            Dim field As New Rdl.FieldType()
            field.Name = fieldName
            field.Items = New Object() {fieldName}
            field.ItemsElementName = New Rdl.ItemsChoiceType1() {Rdl.ItemsChoiceType1.DataField}
            Return field
        End Function

        Public Sub WriteXml(ByVal stream As Stream)
            Dim serializer As New XmlSerializer(GetType(Rdl.Report))
            serializer.Serialize(stream, CreateReport())
        End Sub

    End Class
End Namespace

Step2: Create a TableRdlGenerator Class and write the below cobe in TableRdlGenerator class

Imports System.Collections.Generic


Namespace DynamicTable
    Class TableRdlGenerator
        Private _mFields As List(Of String)
        Private _mFieldwidths As List(Of String)

        Public Property Fields() As List(Of String)
            Get
                Return _mFields
            End Get
            Set(ByVal value As List(Of String))
                _mFields = value
            End Set
        End Property
        Public Property FieldWidths() As List(Of String)
            Get
                Return _mFieldwidths
            End Get
            Set(ByVal value As List(Of String))
                _mFieldwidths = value
            End Set
        End Property

        Public Function CreateTable() As Rdl.TableType
            Dim table As New Rdl.TableType()
            table.Name = "Table1"
            table.Items = New Object() {CreateTableColumns(), CreateHeader(), CreateDetails()}
            table.ItemsElementName = New Rdl.ItemsChoiceType21() {Rdl.ItemsChoiceType21.TableColumns, Rdl.ItemsChoiceType21.Header, Rdl.ItemsChoiceType21.Details}
            Return table
        End Function

        Private Function CreateHeader() As Rdl.HeaderType
            Dim header As New Rdl.HeaderType()
            header.Items = New Object() {CreateHeaderTableRows()}
            header.ItemsElementName = New Rdl.ItemsChoiceType20() {Rdl.ItemsChoiceType20.TableRows}
            Return header
        End Function

        Private Function CreateHeaderTableRows() As Rdl.TableRowsType
            Dim headerTableRows As New Rdl.TableRowsType()
            headerTableRows.TableRow = New Rdl.TableRowType() {CreateHeaderTableRow()}
            Return headerTableRows
        End Function

        Private Function CreateHeaderTableRow() As Rdl.TableRowType
            Dim headerTableRow As New Rdl.TableRowType()
            headerTableRow.Items = New Object() {CreateHeaderTableCells(), "0.20pt"}
            Return headerTableRow
        End Function

        Private Function CreateHeaderTableCells() As Rdl.TableCellsType
            Dim headerTableCells As New Rdl.TableCellsType()
            headerTableCells.TableCell = New Rdl.TableCellType(_mFields.Count - 1) {}
            For i As Integer = 0 To _mFields.Count - 1
                headerTableCells.TableCell(i) = CreateHeaderTableCell(_mFields(i))
            Next
            Return headerTableCells
        End Function

        Private Function CreateHeaderTableCell(ByVal fieldName As String) As Rdl.TableCellType
            Dim headerTableCell As New Rdl.TableCellType()
            headerTableCell.Items = New Object() {CreateHeaderTableCellReportItems(fieldName)}
            Return headerTableCell
        End Function

        Private Function CreateHeaderTableCellReportItems(ByVal fieldName As String) As Rdl.ReportItemsType
            Dim headerTableCellReportItems As New Rdl.ReportItemsType()
            headerTableCellReportItems.Items = New Object() {CreateHeaderTableCellTextbox(fieldName)}
            Return headerTableCellReportItems
        End Function

        Private Function CreateHeaderTableCellTextbox(ByVal fieldName As String) As Rdl.TextboxType
            Dim headerTableCellTextbox As New Rdl.TextboxType()
            headerTableCellTextbox.Name = fieldName.Trim + "_Header"
            headerTableCellTextbox.Items = New Object() {fieldName, CreateHeaderTableCellTextboxStyle(), True}
            headerTableCellTextbox.ItemsElementName = New Rdl.ItemsChoiceType14() {Rdl.ItemsChoiceType14.Value, Rdl.ItemsChoiceType14.Style, Rdl.ItemsChoiceType14.CanGrow}
            Return headerTableCellTextbox
        End Function

        Private Function CreateHeaderTableCellTextboxStyle() As Rdl.StyleType
            Dim headerTableCellTextboxStyle As New Rdl.StyleType()

            headerTableCellTextboxStyle.Items = New Object() {"Bold", "10pt", "White", "Center", bordersty(), "Middle"}

            headerTableCellTextboxStyle.ItemsElementName = New Rdl.ItemsChoiceType5() {Rdl.ItemsChoiceType5.FontWeight, Rdl.ItemsChoiceType5.FontSize, Rdl.ItemsChoiceType5.BackgroundColor, Rdl.ItemsChoiceType5.TextAlign, Rdl.ItemsChoiceType5.BorderStyle, Rdl.ItemsChoiceType5.VerticalAlign}
            Return headerTableCellTextboxStyle
        End Function

        Private Function CreateTableCellTextboxStyle() As Rdl.StyleType
            Dim style As New Rdl.StyleType()
            style.Items = New Object() {"Left", "Normal", "7pt", bordersty()}
            style.ItemsElementName = New Rdl.ItemsChoiceType5() {Rdl.ItemsChoiceType5.TextAlign, Rdl.ItemsChoiceType5.FontWeight, Rdl.ItemsChoiceType5.FontSize, Rdl.ItemsChoiceType5.BorderStyle}
            Return style
        End Function
        Private Function bordersty() As Rdl.BorderColorStyleWidthType
            Dim style As New Rdl.BorderColorStyleWidthType()
            style.Items = New Object() {"Solid"}
            style.ItemsElementName = New Rdl.ItemsChoiceType3() {Rdl.ItemsChoiceType3.[Default]}
            Return style
        End Function
        Private Function CreateDetails() As Rdl.DetailsType
            Dim details As New Rdl.DetailsType()
            details.Items = New Object() {CreateTableRows()}
            Return details
        End Function

        Private Function CreateTableRows() As Rdl.TableRowsType
            Dim tableRows As New Rdl.TableRowsType()
            tableRows.TableRow = New Rdl.TableRowType() {CreateTableRow()}
            Return tableRows
        End Function

        Private Function CreateTableRow() As Rdl.TableRowType
            Dim tableRow As New Rdl.TableRowType()
            tableRow.Items = New Object() {CreateTableCells(), "0.20in"}
            Return tableRow
        End Function

        Private Function CreateTableCells() As Rdl.TableCellsType
            Dim tableCells As New Rdl.TableCellsType()
            tableCells.TableCell = New Rdl.TableCellType(_mFields.Count - 1) {}
            For i As Integer = 0 To _mFields.Count - 1
                tableCells.TableCell(i) = CreateTableCell(_mFields(i))
            Next
            Return tableCells
        End Function

        Private Function CreateTableCell(ByVal fieldName As String) As Rdl.TableCellType
            Dim tableCell As New Rdl.TableCellType()
            tableCell.Items = New Object() {CreateTableCellReportItems(fieldName)}
            Return tableCell
        End Function

        Private Function CreateTableCellReportItems(ByVal fieldName As String) As Rdl.ReportItemsType
            Dim reportItems As New Rdl.ReportItemsType()
            reportItems.Items = New Object() {CreateTableCellTextbox(fieldName)}
            Return reportItems
        End Function

        Private Function CreateTableCellTextbox(ByVal fieldName As String) As Rdl.TextboxType
            Dim textbox As New Rdl.TextboxType()
            textbox.Name = fieldName.Trim
            textbox.Items = New Object() {"=Fields!" + fieldName.Trim + ".Value", CreateTableCellTextboxStyle(), True}
            textbox.ItemsElementName = New Rdl.ItemsChoiceType14() {Rdl.ItemsChoiceType14.Value, Rdl.ItemsChoiceType14.Style, Rdl.ItemsChoiceType14.CanGrow}
            Return textbox
        End Function

        Private Function CreateTableColumns() As Rdl.TableColumnsType
            Dim tableColumns As New Rdl.TableColumnsType()
            tableColumns.TableColumn = New Rdl.TableColumnType(_mFields.Count - 1) {}
            For i As Integer = 0 To _mFields.Count - 1
                tableColumns.TableColumn(i) = CreateTableColumn(_mFieldwidths(i))
            Next
            Return tableColumns
        End Function

        Private Function CreateTableColumn(ByVal fldWidth As String) As Rdl.TableColumnType
            Dim tableColumn As New Rdl.TableColumnType()
            tableColumn.Items = New Object() {fldWidth.Trim + "in"}
            Return tableColumn
        End Function
    End Class
End Namespace

Step3: Add ReportDefinition Class file 

This file was automatically generated as follows:

Download the xsd file from
    http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition/ReportDefinition.xsd

Run the xsd.exe tool as follows:
    "C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\xsd.exe" /c /namespace:Rdl ReportDefinition.xsd

------------------------------------------------------------------------------
 <auto-generated>
    This code was generated by a tool.
    Runtime Version:2.0.50727.42
   Changes to this file may cause incorrect behavior and will be lost if
     the code is regenerated.
 </auto-generated>
------------------------------------------------------------------------------

 This source code was auto-generated by xsd, Version=2.0.50727.42.


write the below code in vb file

Private Sub ShowReport()
            'Me.reportViewer1.BackColor = System.Drawing.Color.LightSteelBlue
            'Me.reportViewer1.BorderStyle = Forms.BorderStyle.FixedSingle
            'Me.reportViewer1.AutoSizeMode = Forms.AutoSizeMode.GrowAndShrink

            Dim fntFam As New System.Drawing.FontFamily("Arial")

            Dim bmp As New System.Drawing.Bitmap(1, 1)
            Dim graphic As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(bmp)

            Me.reportViewer1.Reset()
            Me.reportViewer1.LocalReport.LoadReportDefinition(m_rdl)
            Me.reportViewer1.LocalReport.DataSources.Add(New ReportDataSource("MyData", m_dataSet.Tables(0)))
            Me.reportViewer1.RefreshReport()
        End Sub

        Private Function GenerateRdl(ByVal allFields As List(Of String), ByVal selectedFields As List(Of String), ByVal selectedFieldWidths As List(Of String)) As MemoryStream

            Dim ms As New MemoryStream()
            Dim gen As New RdlGenerator()
            gen.AllFields = allFields
            gen.SelectedFields = selectedFields
            gen.SelectedFieldWidths = selectedFieldWidths
            gen.WriteXml(ms)
            ms.Position = 0
            Return ms
        End Function

        Private Sub DumpRdl(ByVal rdl As MemoryStream)
#If DEBUG_RDLC Then
Using fs As New FileStream("c:\test.rdlc", FileMode.Create)
rdl.WriteTo(fs)
End Using
#End If
        End Sub

        Private Function GetAvailableFields() As List(Of String)
            Dim dataTable As DataTable = m_dataSet.Tables(0)
            'dataTable.Columns(0).MaxLength = "10"
            'dataTable.Columns(1).MaxLength = "2"


            Dim availableFields As New List(Of String)()
            For i As Integer = 0 To dataTable.Columns.Count - 1
                availableFields.Add(dataTable.Columns(i).ColumnName)
            Next
            Return availableFields
        End Function

        Private Function GetAvailableFieldWidths(ByVal dset As DataTable) As List(Of String)
            'm_dataSet = dset
            'Dim dataTable As DataTable = m_dataSet
            Dim availableFieldWidths As List(Of String) = New List(Of String)


            For i As Integer = 0 To dset.Columns.Count - 1
                Dim width As Single = [Single].MinValue
                Dim tempWidth As Single = [Single].MinValue

                If dset.Rows.Count > 0 Then
                    ' Examine each row to determine if contents require additional width.
                    For Each row As DataRow In dset.Rows
                        tempWidth = Convert.ToString(row(i)).Trim().Length * 0.2F
                        If tempWidth > width Then
                            width = tempWidth
                        End If
                    Next
                Else
                    tempWidth = dset.Columns(i).Caption.Length * 0.2F
                End If

                availableFieldWidths.Add(tempWidth.ToString)
            Next

            Return availableFieldWidths
        End Function
        Private Sub GenerateReport()
            Try
                m_dataSet = New DataSet()
                'm_dataSet.ReadXml(filename);
                m_dataSet = GetDataSet()

                Dim allFields As List(Of String) = GetAvailableFields()
                Dim selectedFieldWidths As List(Of String) = GetAvailableFieldWidths(m_dataSet.Tables(0))
                'List<string> selectedFields = dlg.GetSelectedFields();

                If m_rdl IsNot Nothing Then
                    m_rdl.Dispose()
                End If
                m_rdl = GenerateRdl(allFields, allFields, selectedFieldWidths)
                DumpRdl(m_rdl)

                ShowReport()
            Catch ex As Exception
                MessageBox.Show(ex.Message, "Error")
            End Try
        End Sub

        Private Sub btnGenerate_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnGenerate.Click

            If txtFDate.Text = "" Then
                MsgBox("Enter From date")
                txtFDate.Focus()
                Exit Sub
            End If
            If txtTDate.Text = "" Then
                MsgBox("Enter To date")
                txtTDate.Focus()
                Exit Sub
            End If

            If rdbtnInvoice.IsChecked = False Then
               MsgBox("Select Invoice Wise Detail")
               rdbtnInvoice.Focus()
                Exit Sub
            End If

            Dim mstype As String = ""
            mstype = CType(ddltd.SelectedItem, ValueAndText).Value

            If mstype = "" Then
                MsgBox("Select Tranaction")
                ddltd.Focus()
                Exit Sub
            End If

            GenerateReport()
        End Sub

        Public Function GetDataSet() As DataSet
            Dim ds As DataSet = Nothing
            lblMessage.Content = ""
            Dim msFromdt As String = Utilities.vbConvertdate(txtFDate.Text, "1")
            Dim msTodt As String = Utilities.vbConvertdate(txtTDate.Text, "1")
            Dim ddlSelect As String = CType(ddltd.SelectedItem, ValueAndText).Value

            Try
                ds = objReadData.PSReport(msFromdt, msTodt, BU, Branch, ddlSelect)
            
            Catch ex As Exception
                lblMessage.Content = ex.Message
            End Try
            Return ds
        End Function

No comments:

Post a Comment

SQL SERVER – Disk Space Monitoring – Detecting Low Disk Space on Server

CREATE PROCEDURE [CSMSDVLP].[DiskSpaceMonitor] @mailProfile nvarchar(500), @mailto nvarchar(4000), @threshold INT, @logfile nvarchar(40...