The Crystal Viewer utility is made up of two Windows Forms.
The first form, shown in Figure 1, lists available reports in a ListBox for the
user to select from while the second (ReportViewer) hosts the CrystalViewer
control to display the selected report.
Figure 1 - The Viewer Utility displays available reports in a specific path. The user can hide the two
settings if they wish.
When the user selects an item from the list, the utility
loads the chosen file using the Load method shown above, then establishes the
connection to the database as described above using the value stored in the
Database Server field. The ReportDocument is then passed to the ReportViewer
form which attaches the report to the CrystalViewer using the DataSource
property. Lastly, the main form calls the ReportViewer form’s Show method. If
parameters are required, Crystal Reports automatically opens its own form for
collecting the necessary values and then the report is displayed. Parameters
are discussed in more detail later in this article.
Figure 2 - If the report has parameters, Crystal Reports' "Enter Parameter Values" form will be
The utility will need to know where to look for saved
reports and the name of the database server. These are stored using .NET’s
ApplicationSettings and the end-user has the ability to update those values
using the settings fields at the bottom of the form. ApplicationSettings can
be created in the Settings page of the project Properties as shown in Figure 3,
and then accessed in code. If a user modifies these settings, they will be
persisted in the application.
Figure 3 - The Viewer Utility has two application settings, ReportLocation and Server, which can be defined
in the Project Properties window.
When the form loads, the ListBox is populated using the
Private Sub FillReportList()
Dim FileList As New ArrayList
Dim files() As String = Directory.GetFiles(My.Settings.ReportLocation)
Dim f As FileInfo
For Each filepath As String In files
f = New FileInfo(filepath)
If f.Extension = ".rpt" Then
ListBox1.DataSource = FileList
btnRunReport.Enabled = (FileList.Count > 0)
Catch ex As DirectoryNotFoundException
MessageBox.Show("Report Locations folder is invalid. " & _
"Please edit in Settings.")
Catch ex As Exception
MessageBox.Show("Report List cannot be loaded.")
The ellipses button to the right of the Report Location on
the form opens a FolderBrowserDialog to assist the user in selecting a folder
path. Drag a FolderBrowserDialog component onto the form to use this
functionality. The following code opens up the FolderBrowserDialog then stores
the resulting path to the user setting. If the user changes the path, then the
ListBox is repopulated and the setting is remembered the next time the user
runs the application.
.SelectedPath = ReportLocation.Text
If .SelectedPath <> ReportLocation.Text Then
My.Settings.ReportLocation = .SelectedPath
ReportLocation.Text = .SelectedPath
The Database Server field is a textbox which the users can
type in. The user setting for the database is modified in the same manner as
the ReportLocation setting. A more advanced version of the Crystal Viewer
utility leverages the System.Data.Sql.SqlDataSourceEnumerator class to assist
the end-user in selecting an available SQL Server.
When the user selects a report and clicks the Run Report
button, the following code is executed to load the report, set the connection
and run the report.
Private Sub btnRunReport_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnRunReport.Click
rptDoc = New CrystalDecisions.CrystalReports.Engine.ReportDocument
rptDoc.Load(My.Settings.ReportLocation & "\" & _
ListBox1.SelectedValue.ToString.Trim & ".rpt")
Dim dbname As String = .DatabaseName
Dim integrated As Boolean = .IntegratedSecurity
.SetConnection(My.Settings.Server, dbname, integrated)
Dim frm As New ReportViewer
Catch ex As CrystalDecisions.CrystalReports.Engine.DataSourceException
MessageBox.Show("There was a datasource error loading " & _
"this report. Please check the Server setting.")
Catch ex As Exception
MessageBox.Show("There was an error loading this report. " & _
"The error is coming from the report, not the datasource. " & _
"Please check with the creator of the report you are trying to view.")
The ReportViewer form has a SetReport method which is called
in the above code before returning to call the Show method of the ReportViewer
Public Sub SetReport(ByVal rptDoc As _
CrystalReportViewer1.ReportSource = rptDoc
Figure 4 displays a form which was generated at run time
using a parameter value entered by the end-user.
Figure 4 - This report was dynamically created using a parameter entered at run-time.