Crystal Report And Similar Tool For Printing Document

May i know is there any tutorial on Crystal Report, i want to retrieve some data from database, format it and print it out. Apart from Crystal Report, what other tools is suitable for this Thank you.

Answer this question

Crystal Report And Similar Tool For Printing Document

  • John.Doe

    I have already solved the previous problem. I am really a beginner to crystal report and have no idea on its working principle, is there anyone can provide some information or web tutorial which can guide me from the ground I need to know the basic like how to bound the data to the report and display it properly, how to format the report and do the query to display particular data in the report. Thank you.
  • LalitSRana

    Thanks for your code. I want to do something like this, when the user select a row of the datagridview and press print, it will generate report and allow user to print the report of that selected employee. Now what i have done is only add the crystal report in my solution explorer and setup the OLEDB connection for the crystal report. May i know how to call out the crystal report by clicking the print button, do i need a viewer for that and how to pass the SQL statement to the report so it can retrieve the data properly
     
    I have already extracted the data that i want to display in report using textboxes and datagridview. May i know is there any way for me to pass all these values to the text objects in crystal report Thank you.
     

  • bennett1016

    Ok, lets look at this from a different point of view...

    If i was writing a program that does what you are trying to do I would approach it in the following manner..

    1) Create an employee object

    2) Use a listview to display a list of employee objects rather than a datagrid tying the tag property on the listviewitem to the employee object.

    3) create a routine in the employee object to provide a dataset of the data held within its properties

    You can then access the employee object directly from the listview item clicked event. Then using the code I posted, pass the employee's dataset to the crystal report like so;

    Dim report as new employeeReport

    AddHandler report.ReportGenerated, AddressOf ShowGeneratedReport

    report.Dataset = objEmployee.Dataset

    report.generate

    The current way you have built your app means you should be able to tie the data directly to the report by passing it a dataset containing the employee data. You will need to alter your crystal report so instead of using a database connection to get a schema, it looks at your predefined dataset schema for its fields. You should be able to populate a dataset with the data you have got in the datagrid and then pass this directly to the crystal report baseclass to allow you to print the data.


  • Gunnar Adler

  • museicon

    All crystal needs to bind the datasource to the report is a valid dataset. This is why i sent you my example. You need to create a dataset schema using the IDE that contains all the fields you want to display on your report. This dataset is seperate from your database schema and contain any field name you want. You then use the crystal report designer to bind each field in this dataset to your report. Then make a sql statement that will populate this dataset using AS clauses and sql subqueries where necessary.


  • likong

    THANK YOU !!! THANK YOU !!! THANK YOU !!!

    The code you wrote helped me a lot. I mean it worked perfectly. After 2 + days of different coding.

    If this helps, what I found was that it doesn't metter the values that result in the crystal report table. The only condition is to be the same fields and the name of the table to be identical . In the report will appear the values that result in the code you write, like above .

    Thanks again,

    Mihai - RO.


  • Any ole Joe

    Did you add reference to the crystal reports assemblies Post us the link to the tutorial that you are looking at.

  • Freqy

    There are quite a few software vendors who have got report generating tools. Your choice will probably come down to cost. If you are using VS2005 then you may want to stick with the free version of crystal provided, but you can always find others by googling report generators. As for crystal tutorials, try going to the business objects website as there are walk through examples there.
  • SomeDeveloperPerson

    I have already set the datasource for the crystal report but i dont know how to extract the emp_no from the database and display it using the crystal report text object called Employee_No. Thank you.
     

    CrystalReportViewer1.ActiveViewIndex = 0

    CrystalReportViewer1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle

    CrystalReportViewer1.DisplayGroupTree = False

    CrystalReportViewer1.Dock = System.Windows.Forms.DockStyle.Fill

    CrystalReportViewer1.Location = New System.Drawing.Point(0, 0)

    CrystalReportViewer1.Name = "CrystalReportViewer1"

    Dim QueryString As String = "select * from Emp_Profile WHERE emp_no='E00001'" 'Your Query here

    Dim Con As String = "Provider=SQLOLEDB; Data Source= USER\SQLEXPRESS; Database=UserDatabase; UID=sa ; PWD=sa;"

    Dim Connection As New OleDbConnection(Con) 'Your Database Connection Here

    Connection.Open()

    Dim Adapter As OleDbDataAdapter = New OleDbDataAdapter(QueryString, Connection) 'Passing the query in the connection

    Dim DataSet1 As DataSet = New DataSet() 'DataSet

    Adapter.Fill(DataSet1)

     

    Dim Report As New CrystalReport1

    Report.SetDataSource(DataSet1)

    CrystalReportViewer1.ReportSource = Report


  • stallion_alpa

    Anyone can help me to check the following underlined code The VB.NET 2005 can't recognize the underlined object. I will really appreciate if you can provide me some good Crystal Report web tutorials or information. Thank you.
     

    Dim CrystalReportViewer1 As CrystalDecisions.Windows.Forms.CrystalReportViewer = New CrystalDecisions.Windows.Forms.CrystalReportViewer

    Dim Report As CrystalDecisions.CrystalReports.Engine.ReportDocument = New CrystalDecisions.CrystalReports.Engine.ReportDocument

    CrystalReportViewer1.ActiveViewIndex = 0

    CrystalReportViewer1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle

    CrystalReportViewer1.DisplayGroupTree = False

    CrystalReportViewer1.Dock = System.Windows.Forms.DockStyle.Fill

    CrystalReportViewer1.Location = New System.Drawing.Point(0, 0)

    CrystalReportViewer1.Name = "CrystalReportViewer1"


  • Joeschoe

    Now i am able to display the data from the dataset. First, i select which table i am going to make use under database expert and then you can drag any data field of that table you want to display from Field Explorer. Apart from that, i coded the SQL query which retrieves the appropriate data and fill this into dataset with Adapter. Set this dataset as DataSource of CrystalReport and previous dragged data field will only retrieve the result according to the query.
     
    However, the datafields i can drag into crystal report content must belong to the table that i have set previously. What if i want to sum two data and display this data with a text object of CrystalReport. Even we could add this data in dataset, what about the field that used to display that since there is no data field i could find for that Thank you.
     
     

  • Frank Racis

    I have posted the code below for two classes that I created. One is a base class for all crystal reports and the other is an example of how you would consume this base class. Although I have my own db wrapper you should be able to pick out the bits you need to modify to get it working in your own app. You will need to create a dataset schema and use this to create your crystal report. Then create a stored procedure that will return data in the schema format. You will also notice that I have threaded the report generation as it can be a tad slow! You will also note that I use a workingdialog form so that the user can stop the report generation if required. The event that is fired by this form is handled in the crystal report baseclass cancelling the async op. Hope this helps!

    Imports aDataAccess = MDESys.Global.DataAccess

    Imports aInterfaces = MDESys.Global.Interfaces

    Namespace BaseClasses

    ''' <summary>

    ''' This BaseClass allows you to simplify the report generation of Crystal Reports.

    ''' The report generation is multi-threaded and the report should be shown when the ReportGenerated Event is fired.

    ''' </summary>

    ''' <remarks></remarks>

    Public MustInherit Class CrystalReport

    Implements aInterfaces.IDataAccess

    #Region " Events "

    Public Event ReportGenerated()

    <CLSCompliant(False)> _

    Public Event ReportException(ByVal ex As BespokeException)

    #End Region

    #Region " Fields "

    Protected m_DataSet As DataSet

    Protected m_name As String

    <CLSCompliant(False)> _

    Protected m_reportViewer As ReportViewer

    <CLSCompliant(False)> _

    Private objDatabaseWrapper As aDataAccess.DatabaseWrapper = Nothing

    Protected m_SPName As String

    Protected m_parameters As Parameters

    Protected m_ReportDocument As CrystalDecisions.CrystalReports.Engine.ReportDocument

    <CLSCompliant(False)> _

    Protected m_CrystalReportViewer As CrystalDecisions.Windows.Forms.CrystalReportViewer

    Protected WithEvents bgwReportGeneration As New System.ComponentModel.BackgroundWorker

    <CLSCompliant(False)> _

    Protected WithEvents workingIndicator As WorkingDialog

    Private TaskCancelled As Boolean = False

    Private ReportReadyToView As Boolean = False

    #End Region

    #Region " Properties "

    Public ReadOnly Property Name() As String

    Get

    Return m_name

    End Get

    End Property

    Public ReadOnly Property StoredProcedure() As String

    Get

    Return m_SPName

    End Get

    End Property

    Protected ReadOnly Property Parameters() As Parameters

    Get

    If m_parameters Is Nothing Then

    m_parameters = New Parameters

    End If

    Return m_parameters

    End Get

    End Property

    #End Region

    #Region " Threading and Threaded Methods "

    ' This runs on the background (non UI) thread

    Private Function GetDataSet() As System.Data.DataSet

    Dim objDataSet As DataSet = Nothing

    Try

    ' Validate First...

    If m_SPName.Length = 0 Then

    Throw New BespokeException(Nothing, BespokeException.ErrorType.CRYSTAL_REPORTS_EXCEPTION, "Stored Procedure Name not set. GetDataSet(1). ReportName: " & Me.Name)

    End If

    If Me.bgwReportGeneration.CancellationPending Then

    Exit Try

    End If

    ' Begin the transaction

    objDatabaseWrapper.BeginTransaction()

    ' Set the SP Name

    objDatabaseWrapper.QueryText = m_SPName

    ' Add the Parameters

    objDatabaseWrapper.Parameters.Clear()

    For Each objParameter As Parameter In m_parameters

    objDatabaseWrapper.Parameters.AddWithValue(objParameter.Name, objParameter.Value)

    Next

    If Me.bgwReportGeneration.CancellationPending Then

    Exit Try

    End If

    objDataSet = objDatabaseWrapper.GetDataSet

    Catch ex As BespokeException

    ' Previous Exception was a Bespoke exception to rethrow with the same ErrorType

    Throw New BespokeException(ex, ex.Type, "CrystalReport: GetDataSet(2)")

    Catch ex As Exception

    Throw New BespokeException(ex, BespokeException.ErrorType.GENERIC_ERROR, "CrystalReport: GetDataSet(3)")

    Finally

    objDatabaseWrapper.EndTransaction()

    End Try

    Return objDataSet

    End Function

    ' This method runs on the Background worker thread

    Private Sub ReportGenerationThread_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgwReportGeneration.DoWork

    ' This method runs on the second thread and therefore CANNOT access controls on the form. To access controls on the form you must use a delegate

    Dim ds As DataSet

    Try

    If Me.bgwReportGeneration.CancellationPending Then

    Exit Sub

    End If

    ds = GetDataSet()

    If Me.bgwReportGeneration.CancellationPending Then

    Exit Sub

    End If

    m_ReportDocument.SetDataSource(ds)

    If Me.bgwReportGeneration.CancellationPending Then

    Exit Sub

    End If

    Catch ex As BespokeException

    OnExceptionOccurred(ex)

    Catch ex As Exception

    OnExceptionOccurred(New BespokeException(ex, BespokeException.ErrorType.GENERIC_ERROR, "ReportGenerationThread_DoWork(1)"))

    End Try

    End Sub

    Private Sub ReportGenerationThread_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgwReportGeneration.RunWorkerCompleted

    ' This runs in the UI thread and so can access controls on the form

    workingIndicator.Close()

    If Not TaskCancelled Then

    RaiseEvent ReportGenerated()

    End If

    ' If there was an exception in the BWthread then this should handle it (in theory)

    If e.Error IsNot Nothing Then

    OnExceptionOccurred(New BespokeException(e.Error, BespokeException.ErrorType.GENERIC_ERROR, "ReportGenerationThread_RunWorkerCompleted(1)"))

    End If

    End Sub

    #End Region

    #Region " Methods "

    ''' <summary>

    ''' Use this method to display the report in the report viewer

    ''' </summary>

    ''' <remarks>This should not be called before the ReportGenerated event has been fired.</remarks>

    Public Sub Show()

    Try

    ' Ensure the report is there to view..

    If Not ReportReadyToView Then

    Throw New BespokeException(Nothing, BespokeException.ErrorType.CRYSTAL_REPORTS_EXCEPTION, "You cannot show the report until the Report is Generated")

    End If

    ' create a new report viewer

    m_reportViewer = New ReportViewer

    With m_reportViewer.CrystalReportViewer

    ' Add the required control values here

    .ReportSource = Nothing

    End With

    ' Pass the document to the viewer

    m_reportViewer.CrystalReportViewer.ReportSource = m_ReportDocument

    ' Show the viewer

    m_reportViewer.ShowDialog()

    Catch ex As BespokeException

    Throw New BespokeException(ex, ex.Type, "Show(1)")

    Catch ex As Exception

    Throw New BespokeException(ex, BespokeException.ErrorType.CRYSTAL_REPORTS_EXCEPTION, "Show(1)")

    End Try

    End Sub

    ''' <summary>

    ''' This generates the report on a seperate thread as Crystal Reports are performance heavy.

    ''' </summary>

    ''' <param name="parDatabaseWrapper"></param>

    ''' <remarks></remarks>

    <CLSCompliant(False)> _

    Protected Sub CreateReport(ByRef parDatabaseWrapper As aDataAccess.DatabaseWrapper)

    workingIndicator = New WorkingDialog

    AddHandler workingIndicator.CancelTask, AddressOf CancelReportGeneration

    workingIndicator.Show()

    Try

    objDatabaseWrapper = parDatabaseWrapper

    If Me.bgwReportGeneration.IsBusy Then

    Exit Sub

    End If

    Me.bgwReportGeneration.WorkerReportsProgress = False

    Me.bgwReportGeneration.WorkerSupportsCancellation = True

    If Me.bgwReportGeneration.CancellationPending Then

    Exit Sub

    End If

    Me.bgwReportGeneration.RunWorkerAsync()

    Catch ex As BespokeException

    Throw New BespokeException(ex, ex.Type, "CreateReport(1)")

    Catch ex As Exception

    Throw New BespokeException(ex, BespokeException.ErrorType.CRYSTAL_REPORTS_EXCEPTION, "CreateReport(2)")

    End Try

    End Sub

    Private Sub CancelReportGeneration()

    Me.bgwReportGeneration.CancelAsync() ' For worker thread

    TaskCancelled = True ' For UI Thread

    End Sub

    #End Region

    #Region " Interface Implementation "

    #Region " IDataAccess "

    <CLSCompliant(False)> _

    Public ReadOnly Property DatabaseWrapper() As aDataAccess.DatabaseWrapper Implements aInterfaces.IDataAccess.DatabaseWrapper

    Get

    Return objDatabaseWrapper

    End Get

    End Property

    #End Region

    #End Region

    #Region " Error Handling "

    Private Sub OnExceptionOccurred(ByVal ex As BespokeException)

    RaiseEvent ReportException(ex)

    End Sub

    #End Region

    End Class

    End Namespace

    The class below consumes the above base class.

    Imports aErrorHandling = MDESys.Global.ErrorHandling

    Imports aDataAccess = MDESys.Global.DataAccess

    Imports aReporting = MDESys.Reporting

    Namespace Reports

    Public Class SingleArcher

    Inherits aReporting.BaseClasses.CrystalReport

    #Region " Initialise and Finalise "

    Public Class RequiredParameters

    Public Archer_ID As Int64

    End Class

    <CLSCompliant(False)> _

    Public Sub New(ByRef parDatabaseWrapper As aDataAccess.DatabaseWrapper, ByRef parameters As RequiredParameters)

    Try

    If parameters.Archer_ID = 0 Then

    Throw New aErrorHandling.Exceptions.BespokeException(Nothing, BespokeException.ErrorType.CRYSTAL_REPORTS_EXCEPTION, "Cannot generate the report without the archers ID")

    End If

    MyBase.m_SPName = "MDE_RPT_SINGLE_ARCHER_DETAILS"

    MyBase.m_ReportDocument = New rptSingleArcher

    MyBase.Parameters.AddWithValue("@Archer_ID", parameters.Archer_ID)

    MyBase.CreateReport(parDatabaseWrapper)

    Catch ex As aErrorHandling.Exceptions.BespokeException

    Throw New aErrorHandling.Exceptions.BespokeException(ex, ex.Type, "SingleArcher. New(1)")

    Catch ex As Exception

    Throw New aErrorHandling.Exceptions.BespokeException(ex, BespokeException.ErrorType.CRYSTAL_REPORTS_EXCEPTION, "SingleArcher. New(2)")

    End Try

    End Sub

    #End Region

    End Class

    End Namespace

    You would need to create a version of the class above for each report you have. This then means that in your form, you can simply call the following...

    Private Sub Archer_Print(ByVal sender As System.Object, ByVal e As System.EventArgs)

    Dim parameters As Reports.SingleArcher.RequiredParameters = Nothing

    Try

    ' set the parameters

    parameters = New Reports.SingleArcher.RequiredParameters

    parameters.Archer_ID = m_Archer.ID

    ' create the report.

    report = New Reports.SingleArcher(My.Application.DatabaseWrapper, parameters)

    AddHandler report.ReportGenerated, AddressOf ShowGeneratedReport

    Catch ex As BespokeException

    OnExceptionOccurred(ex)

    Catch ex As Exception

    OnExceptionOccurred(New BespokeException(ex, BespokeException.ErrorType.GENERIC_ERROR, "Print Archer (1)"))

    End Try

    End Sub

    Private Sub ShowGeneratedReport()

    report.Show()

    End Sub


  • martona

    your very welcome, glad i could be of assistance
  • babarzhr

    Never used crystal on the web before but you may find it easier to create the report on the server, save it as a pdf, and then stream the pdf to the browser.

    Question; the code you have posted above, is this in a seperate dll to the webproject Where exactly are you trying to create the report and where have you put this code

    Need more info to help you out...


  • Crystal Report And Similar Tool For Printing Document