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.
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.
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.
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;
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.
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.
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 .
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.
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"
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
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
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.
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
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
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()
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
Crystal Report And Similar Tool For Printing Document
John.Doe
LalitSRana
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
Tis link maybe useful for u...
http://msdn2.microsoft.com/en-us/vstudio/aa700872.aspx
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
Freqy
SomeDeveloperPerson
CrystalReportViewer1.ActiveViewIndex = 0
CrystalReportViewer1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
CrystalReportViewer1.DisplayGroupTree =
FalseCrystalReportViewer1.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 HereConnection.Open()
Dim Adapter As OleDbDataAdapter = New OleDbDataAdapter(QueryString, Connection) 'Passing the query in the connection Dim DataSet1 As DataSet = New DataSet() 'DataSetAdapter.Fill(DataSet1)
Dim Report As New CrystalReport1Report.SetDataSource(DataSet1)
CrystalReportViewer1.ReportSource = Report
stallion_alpa
CrystalReportViewer1.ActiveViewIndex = 0
CrystalReportViewer1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
CrystalReportViewer1.DisplayGroupTree =
FalseCrystalReportViewer1.Dock = System.Windows.Forms.DockStyle.Fill
CrystalReportViewer1.Location =
New System.Drawing.Point(0, 0)CrystalReportViewer1.Name =
"CrystalReportViewer1"Joeschoe
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.DataAccessImports
aInterfaces = MDESys.Global.InterfacesNamespace
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 Thenm_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 transactionobjDatabaseWrapper.BeginTransaction()
' Set the SP NameobjDatabaseWrapper.QueryText = m_SPName
' Add the ParametersobjDatabaseWrapper.Parameters.Clear()
For Each objParameter As Parameter In m_parametersobjDatabaseWrapper.Parameters.AddWithValue(objParameter.Name, objParameter.Value)
Next If Me.bgwReportGeneration.CancellationPending Then Exit Try End IfobjDataSet = 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)") FinallyobjDatabaseWrapper.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 Ifds = GetDataSet()
If Me.bgwReportGeneration.CancellationPending Then Exit Sub End Ifm_ReportDocument.SetDataSource(ds)
If Me.bgwReportGeneration.CancellationPending Then Exit Sub End If Catch ex As BespokeExceptionOnExceptionOccurred(ex)
Catch ex As ExceptionOnExceptionOccurred(
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 formworkingIndicator.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 ThenOnExceptionOccurred(
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 viewerm_reportViewer =
New ReportViewer With m_reportViewer.CrystalReportViewer ' Add the required control values here.ReportSource =
Nothing End With ' Pass the document to the viewerm_reportViewer.CrystalReportViewer.ReportSource = m_ReportDocument
' Show the viewerm_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 CancelReportGenerationworkingIndicator.Show()
TryobjDatabaseWrapper = 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 threadTaskCancelled =
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 ClassEnd
NamespaceThe class below consumes the above base class.
Imports
aErrorHandling = MDESys.Global.ErrorHandlingImports
aDataAccess = MDESys.Global.DataAccessImports
aReporting = MDESys.ReportingNamespace
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 ClassEnd
NamespaceYou 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 parametersparameters =
New Reports.SingleArcher.RequiredParametersparameters.Archer_ID = m_Archer.ID
' create the report.report =
New Reports.SingleArcher(My.Application.DatabaseWrapper, parameters) AddHandler report.ReportGenerated, AddressOf ShowGeneratedReport Catch ex As BespokeExceptionOnExceptionOccurred(ex)
Catch ex As ExceptionOnExceptionOccurred(
New BespokeException(ex, BespokeException.ErrorType.GENERIC_ERROR, "Print Archer (1)")) End Try End Sub Private Sub ShowGeneratedReport()report.Show()
End Submartona
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...