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
displayed.
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
following method:
Private Sub FillReportList()
Try
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
FileList.Add(f.Name.Replace(".rpt", ""))
End If
Next
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.")
End Try
End Sub
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.
With FolderBrowserDialog1
.SelectedPath = ReportLocation.Text
.ShowDialog()
If .SelectedPath <> ReportLocation.Text Then
My.Settings.ReportLocation = .SelectedPath
ReportLocation.Text = .SelectedPath
FillReportList()
End If
End With
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")
Try
With rptDoc.DataSourceConnections(0)
Dim dbname As String = .DatabaseName
Dim integrated As Boolean = .IntegratedSecurity
.SetConnection(My.Settings.Server, dbname, integrated)
End With
rptDoc.Refresh()
Dim frm As New ReportViewer
frm.SetReport(rptDoc)
frm.Show()
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.")
End Try
End Sub
The ReportViewer form has a SetReport method which is called
in the above code before returning to call the Show method of the ReportViewer
form.
Public Sub SetReport(ByVal rptDoc As _
CrystalDecisions.CrystalReports.Engine.ReportDocument)
CrystalReportViewer1.ReportSource = rptDoc
End Sub
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.