Click here to Skip to main content
15,887,596 members
Articles / Programming Languages / C#
Article

Dynamic Crystal Report with C#

Rate me:
Please Sign up or sign in to vote.
4.84/5 (89 votes)
29 Sep 2007CPOL2 min read 549.8K   24.2K   159   92
This program shows how to dynamically load data from a database and application into the Crystal Report
Screenshot - pic2.jpg

Introduction

This program shows how to dynamically load data from a database and application into the Crystal Report. By using this program, we can customize a Crystal Report to some limit at run time of the application like specifying which field (Columns of a particular table) should be displayed in the report.

Background

This problem arose because a group of students from SLIIT asked me how to dynamically generate a Crystal Report using C# 2.0 (.NET 2005). I tried to find a solution for this by searching many forums and sites, but unfortunately I couldn't find any solution for that. Some forums said that there is no way to create dynamic Crystal Reports using .NET 2005. Finally, I found a way to do that.

Using the Code

  1. Create a C# project or add a Form to your existing project.

    Now you can add Checkboxes that correspond to columns of a particular table that should be displayed in the Crystal Report and CrystalReportViewer control to the form.

Screenshot - pic4.jpg

For this demonstration, I have created a database called db1.mdb (in bin\Debug) using Access and created a table called Customer.

  1. Add a DataSet (*.xsd file) to your project using add -> New Items in solution explorer. After that, add a DataTable to the DataSet.

    Screenshot - pic5.jpg

    Add columns to DataTable and name them Column1, Column2, and so on. The number of columns depends on how many columns should be displayed in the Crystal report.

  2. Add a Crystal Report into the project and using the Report Wizard, choose ADO.NET DataSets of the Project data source as the data source of the Crystal Report and select Customer data table of DataSet1 as the selected table of the Crystal Report. Then select fields to be displayed in your report. Then remove Column1…, Column5 objects in Section 2 of the Crystal Report.

    Screenshot - pic7.jpg

    Screenshot - pic8.jpg

  3. Now add parameters called col1, col2col5 (the number of parameters should be equal to the number of columns displayed in the Crystal Report.) using Field Explorer.

    Screenshot - pic9.jpg

  4. Add the following method to your Form for Create SQL SELECT query and assign values to parameters of the Crystal Report according to user selected columns that should be displayed on your report.

    C#
    /// <summary>
    /// This method is used to 
    /// 1. create SELECT query according to the selected column names and 
    /// 2. create parameters and assign values for that parameter
    /// that correspond to the crystal report.
    /// NOTE: This parameter is used to display Column names of the 
    /// Crystal Report according to the user selection.
    /// </summary>
    /// <returns></returns>
    private string CreateSelectQueryAndParameters()
    {
        ReportDocument reportDocument;
        ParameterFields paramFields;
        
        ParameterField paramField;
        ParameterDiscreteValue paramDiscreteValue;
    
        reportDocument = new ReportDocument();
        paramFields = new ParameterFields();
                   
        string query = "SELECT ";
        int columnNo = 0;                
    
        if (chbCode.Checked)
        {
            columnNo++;
            query = query.Insert(query.Length, "Code as Column" +
            columnNo.ToString());
    
            paramField = new ParameterField();
            paramField.Name = "col" + columnNo.ToString();
            paramDiscreteValue = new ParameterDiscreteValue();
            paramDiscreteValue.Value = "Customer Code";
            paramField.CurrentValues.Add(paramDiscreteValue);
            //Add the paramField to paramFields
            paramFields.Add(paramField);
        }
        if (chbFirstName.Checked)
        {
            columnNo++;
            if (query.Contains("Column"))
            {
                query = query.Insert(query.Length, ", ");
            }
            query = query.Insert(query.Length, "FirstName as Column" +
            columnNo.ToString());
            
            paramField = new ParameterField();
            paramField.Name = "col" + columnNo.ToString();
            paramDiscreteValue = new ParameterDiscreteValue();
            paramDiscreteValue.Value = "First Name";
            paramField.CurrentValues.Add(paramDiscreteValue);
            //Add the paramField to paramFields
            paramFields.Add(paramField);
        }
        if (chbLastName.Checked)
        {
            columnNo++; //To determine Column number
            if (query.Contains("Column"))
            {
                query = query.Insert(query.Length, ", ");
            }
            query = query.Insert(query.Length, "LastName as Column" +
            columnNo.ToString());
                            
            paramField = new ParameterField();
            paramField.Name = "col" + columnNo.ToString();
            paramDiscreteValue = new ParameterDiscreteValue();
            paramDiscreteValue.Value = "Last Name";
            paramField.CurrentValues.Add(paramDiscreteValue);
            //Add the paramField to paramFields
            paramFields.Add(paramField);
        }
        if (chbAddress.Checked)
        {
            columnNo++;
            if (query.Contains("Column"))
            {
                query = query.Insert(query.Length, ", ");
            }
            query = query.Insert(query.Length, "Address as Column" +
            columnNo.ToString());
                            
            paramField = new ParameterField();
            paramField.Name = "col" + columnNo.ToString();
            paramDiscreteValue = new ParameterDiscreteValue();
            paramDiscreteValue.Value = "Address";
            paramField.CurrentValues.Add(paramDiscreteValue);
            //Add the paramField to paramFields
            paramFields.Add(paramField);
        }
        if (chbPhone.Checked)
        {
            columnNo++;
            if (query.Contains("Column"))
            {
                query = query.Insert(query.Length, ", ");
            }
            query = query.Insert(query.Length, "Phone as Column" +
            columnNo.ToString());
    
            paramField = new ParameterField();
            paramField.Name = "col" + columnNo.ToString();
            paramDiscreteValue = new ParameterDiscreteValue();
            paramDiscreteValue.Value = "Phone";
            paramField.CurrentValues.Add(paramDiscreteValue);
            //Add the paramField to paramFields
            paramFields.Add(paramField);
        }
    
        //if there is any remaining parameter, assign empty value for that 
        //parameter.
        for (int i = columnNo; i < 5; i++)
        {
            columnNo++;
            paramField = new ParameterField();
            paramField.Name = "col" + columnNo.ToString();
            paramDiscreteValue = new ParameterDiscreteValue();
            paramDiscreteValue.Value = "";
            paramField.CurrentValues.Add(paramDiscreteValue);
            //Add the paramField to paramFields
            paramFields.Add(paramField);
        }
               
        crystalReportViewer1.ParameterFieldInfo = paramFields;
        
        query += " FROM Customer" ;
        return query;
    }
    //
  5. Add the following method to the button click event to display a report when the user presses the button:

    C#
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Data.OleDb;
    
    using CrystalDecisions.CrystalReports.Engine;
    using CrystalDecisions.ReportSource;
    using CrystalDecisions.Shared;
    using CrystalDecisions.Windows.Forms;
    
    namespace app5
    {
        public partial class Form1 : Form
        {
            CrystalReport1 objRpt;
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                objRpt = new CrystalReport1();
    
                string connString = "Provider=Microsoft.Jet.OLEDB.4.0;" +
                    "Data Source=|DataDirectory|\\db1.mdb"; 
               
                //Get Select query String and add parameters to the 
                //Crystal report.
                string query = CreateSelectQueryAndParameters();
    
                //if there is no item select, then exit from the method.
                if (!query.Contains("Column"))
                {
                    MessageBox.Show("No selection to display!");
                    return;
                }
    
                try
                {
                    OleDbConnection Conn = new OleDbConnection(connString);
    
                    OleDbDataAdapter adepter = 
                    new OleDbDataAdapter(query, connString);
                    DataSet1 Ds = new DataSet1();
    
                    adepter.Fill(Ds, "Customer");
                    
                    objRpt.SetDataSource(Ds);
                    crystalReportViewer1.ReportSource = objRpt;
                }
                catch (OleDbException oleEx)
                {
                    MessageBox.Show(oleEx.Message);
                }
                catch (Exception Ex)
                {
                    MessageBox.Show(Ex.Message);
                }
            }

History

  • 29th September, 2007: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Sri Lanka Sri Lanka
I'm working with SAP and Microsoft Technologies such as C#, MS SQL server, ASP.NET, ASP.NET MVC, WebAPI.

Comments and Discussions

 
Questionset column width at runtime Pin
PRADEaZX4-Jul-22 4:18
PRADEaZX4-Jul-22 4:18 
QuestionNeed Help and TY Pin
Jorge De La Cruz28-Feb-22 7:17
Jorge De La Cruz28-Feb-22 7:17 
QuestionSome people had asked this converted to VB.NET code. Pin
Member 1493882314-Apr-21 8:15
Member 1493882314-Apr-21 8:15 
VB.NET conversion

Imports System.Data.OleDb
Imports CrystalDecisions.CrystalReports.Engine
Imports CrystalDecisions.Shared

Public Class Form1

    Private objRpt As ReportDocument = Nothing
    Private Conn As OleDbConnection = Nothing
    Private adapter As OleDbDataAdapter = Nothing
    Private ds As DataSet = Nothing
    Private query As String = String.Empty

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        If objRpt IsNot Nothing Then
            Try
                objRpt.Close()
            Catch ex As Exception
            End Try
        End If

        If ds IsNot Nothing Then
            Try
                ds.Tables.Clear()
            Catch ex As Exception
            End Try
        End If

        objRpt = Nothing
        Conn = Nothing
        adapter = Nothing
        ds = Nothing
        query = String.Empty

        Dim connString As String = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=|DataDirectory|\db1.mdb"

        query = CreateSelectQueryAndParameters()

        If Not query.Contains("Column") Then
            MessageBox.Show("No selection to display!")
            Return
        End If

        Try

            Conn = New OleDbConnection(connString)
            adapter = New OleDbDataAdapter(query, connString)
            Conn.Open()
            ds = New DataSet1()
            adapter.Fill(ds, "Customer")
            objRpt = New CrystalReport1()
            objRpt.SetDataSource(ds)
            CrystalReportViewer1.ReportSource = objRpt
            Conn.Close()

        Catch oleEx As OleDbException
            MessageBox.Show(oleEx.Message)
        Catch Ex As Exception
            MessageBox.Show(Ex.Message)
        End Try

    End Sub

    Private Function CreateSelectQueryAndParameters() As String

        Dim paramFields As ParameterFields = New ParameterFields()
        Dim paramField As ParameterField
        Dim paramDiscreteValue As ParameterDiscreteValue
        Dim query As String = "SELECT "
        Dim columnNo As Integer = 0

        If chbCode.Checked Then

            columnNo += 1
            query = query.Insert(query.Length, "Code as Column" + columnNo.ToString())

            paramField = New ParameterField With {
                .Name = "col" + columnNo.ToString
            }
            paramDiscreteValue = New ParameterDiscreteValue With {
                .Value = "Customer Code"
            }
            paramField.CurrentValues.Add(paramDiscreteValue)
            paramFields.Add(paramField)

        End If

        If chbFirstName.Checked Then

            columnNo += 1

            If query.Contains("Column") Then
                query = query.Insert(query.Length, ", ")
            End If

            query = query.Insert(query.Length, "FirstName as Column" + columnNo.ToString())

            paramField = New ParameterField With {
                .Name = "col" + columnNo.ToString
            }
            paramDiscreteValue = New ParameterDiscreteValue With {
                .Value = "First Name"
            }
            paramField.CurrentValues.Add(paramDiscreteValue)
            paramFields.Add(paramField)

        End If

        If chbLastName.Checked Then

            columnNo += 1

            If query.Contains("Column") Then
                query = query.Insert(query.Length, ", ")
            End If

            query = query.Insert(query.Length, "LastName as Column" + columnNo.ToString())

            paramField = New ParameterField With {
                .Name = "col" + columnNo.ToString
            }
            paramDiscreteValue = New ParameterDiscreteValue With {
                .Value = "Last Name"
            }
            paramField.CurrentValues.Add(paramDiscreteValue)
            paramFields.Add(paramField)

        End If

        If chbAddress.Checked Then

            columnNo += 1

            If query.Contains("Column") Then
                query = query.Insert(query.Length, ", ")
            End If

            query = query.Insert(query.Length, "Address as Column" + columnNo.ToString())

            paramField = New ParameterField With {
                .Name = "col" + columnNo.ToString
            }
            paramDiscreteValue = New ParameterDiscreteValue With {
                .Value = "Address"
            }
            paramField.CurrentValues.Add(paramDiscreteValue)
            paramFields.Add(paramField)

        End If

        If chbPhone.Checked Then

            columnNo += 1

            If query.Contains("Column") Then
                query = query.Insert(query.Length, ", ")
            End If

            query = query.Insert(query.Length, "Phone as Column" + columnNo.ToString())

            paramField = New ParameterField With {
                .Name = "col" + columnNo.ToString
            }
            paramDiscreteValue = New ParameterDiscreteValue With {
                .Value = "Phone"
            }
            paramField.CurrentValues.Add(paramDiscreteValue)
            paramFields.Add(paramField)

        End If

        For i As Integer = columnNo To 5 - 1

            columnNo += 1

            paramField = New ParameterField With {
                .Name = "col" + columnNo.ToString
            }
            paramDiscreteValue = New ParameterDiscreteValue With {
                .Value = String.Empty
            }
            paramField.CurrentValues.Add(paramDiscreteValue)
            paramFields.Add(paramField)

        Next

        CrystalReportViewer1.ParameterFieldInfo = paramFields

        query += " FROM Customer"
        Return query

    End Function

    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing

        If objRpt IsNot Nothing Then
            Try
                objRpt.Close()
            Catch ex As Exception
            End Try
            objRpt = Nothing
        End If

        If Conn IsNot Nothing Then
            If Conn.State = ConnectionState.Open Then
                Try
                    Conn.Close()
                Catch ex As Exception
                End Try
            End If
            Conn = Nothing
        End If

        If ds IsNot Nothing Then
            Try
                ds.Tables.Clear()
            Catch ex As Exception
            End Try
            ds = Nothing
        End If

    End Sub

End Class


modified 15-Apr-21 4:26am.

QuestionThs is really good stuff Pin
Member 1493882314-Apr-21 2:51
Member 1493882314-Apr-21 2:51 
QuestionVery Good job Pin
evry1falls26-May-20 0:02
evry1falls26-May-20 0:02 
Questionthank you Pin
Member 1021805212-Apr-17 2:23
Member 1021805212-Apr-17 2:23 
QuestionMissing Parameter Values Pin
Member 1109148018-Sep-14 1:28
Member 1109148018-Sep-14 1:28 
QuestionCrystal Report for VS2010 with SQL CE Pin
Shoukat Ali Laghari15-Jul-14 19:25
Shoukat Ali Laghari15-Jul-14 19:25 
QuestionExact Article Searched Pin
Wafi Supri29-Apr-14 22:27
Wafi Supri29-Apr-14 22:27 
AnswerRe: Exact Article Searched Pin
Manjula Wickramathunga1-Jun-14 23:40
Manjula Wickramathunga1-Jun-14 23:40 
QuestionCan I have VB.NET Code Pin
Member 28684594-Mar-14 1:14
Member 28684594-Mar-14 1:14 
QuestionU can suppress both Label and Field Pin
Srinivasarao Nalam7-Oct-13 21:14
Srinivasarao Nalam7-Oct-13 21:14 
QuestionPlease help :) Pin
joni50para28-Aug-13 5:17
joni50para28-Aug-13 5:17 
AnswerRe: Please help :) Pin
Manjula Wickramathunga28-Aug-13 18:35
Manjula Wickramathunga28-Aug-13 18:35 
GeneralRe: Please help :) Pin
joni50para31-Aug-13 23:32
joni50para31-Aug-13 23:32 
GeneralRe: Please help :) Pin
Ag_Sharad11-Dec-13 21:19
Ag_Sharad11-Dec-13 21:19 
GeneralGreat work.... Pin
RaviJPatel27-Jul-13 7:04
RaviJPatel27-Jul-13 7:04 
GeneralMy vote of 5 Pin
gorgias9921-Feb-13 22:01
gorgias9921-Feb-13 22:01 
GeneralRe: My vote of 5 Pin
robonmatt29-May-13 23:02
robonmatt29-May-13 23:02 
QuestionNeed a help Pin
riffayu18-Dec-12 18:21
riffayu18-Dec-12 18:21 
BugEnter parameter values crystal reports in c# Pin
CHAITANYA KIRAN KASANI5-Dec-12 21:45
CHAITANYA KIRAN KASANI5-Dec-12 21:45 
GeneralRe: Enter parameter values crystal reports in c# Pin
fresh_girl14-May-14 21:06
fresh_girl14-May-14 21:06 
GeneralRe: Enter parameter values crystal reports in c# Pin
CHAITANYA KIRAN KASANI5-Jun-14 1:27
CHAITANYA KIRAN KASANI5-Jun-14 1:27 
GeneralRe: Enter parameter values crystal reports in c# Pin
Jorge De La Cruz28-Feb-22 7:02
Jorge De La Cruz28-Feb-22 7:02 
Questionhi Pin
Nywalikar22-Nov-12 0:43
Nywalikar22-Nov-12 0:43 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.