Many reports require parameters, for example, if they are
populated with a stored procedure that takes parameters. The ParameterFields
property of a loaded report will enable you to discover and set values for the
parameters necessary to run the report.
As mentioned previously, by default, a report is saved with
its original data in place. When the user re-opens the report, it will show
that saved data. Refreshing the report (by clicking the CrystalViewer’s Refresh
icon or in code), will force another query of the database and the Crystal
Report “Enter Parameter Values” window will open if necessary. For each
parameter that the report requires, the window will display the parameter name,
the PromptingText value that was saved with the report , a textbox to enter the
value (or a drop down list if there are default values to choose from) and a
checkbox for using a Null value for the parameter. If a report collects multiple
parameters, the end-user will see one page per parameter with Next and Back
buttons, as shown in Figure 5, until they reach the final parameter which then
prompts them to Finish.
Figure 5 - If there are more than one parameter required, a separate page will be displayed for each
parameter.
If you do not wish the user to see the saved data when first
opening the report, you can refresh the report programmatically using the
Refresh method. This will cause the Enter Parameter Values screen to appear
before the report.
A more advanced approach would be to iterate through the
report’s ParameterField collection and dynamically add labels and input
controls to single form which can be presented to the end user, rather than
using the default parameter form that the report displays. While building a
dynamic form is out of scope for this particular article, the code below shows
what to do with the values after they have been collected.
Once the user has entered the values in the dynamically
built form, store the values in an ArrayList. The ArrayList works well in this
scenario because it is able to store a variety of types. This is important
because the parameters will expect properly typed data (Strings, Booleans,
dates, etc.) The following code then takes an ArrayList and sets each item in
the ArrayList to the value of each ParameterField in the report. The code
assumes that you have proper types as well as the correct number of parameters
in your ArrayList and that they are in the same order as the parameters. All of
these details are available from the ReportDocument object and should be
accounted for when building the dynamic form.
The code creates a DiscreteValue whose Value property is set
to the value from the ArrayList, then adds this DiscreteValue object to a
ParameterValues collection. Then the ParameterValues collection is applied to
the particular parameter. The reason the parameter takes a collection of values
rather than a single value is because it is possible to have a selection of
appropriate values for the end-user to choose from.
Private Sub UpdateReportParameters(ByVal params As
ArrayList)
Dim discreteVal As New CrystalDecisions.Shared.ParameterDiscreteValue
Dim currVals As New
CrystalDecisions.Shared.ParameterValues
Dim paramField As _
CrystalDecisions.CrystalReports.Engine.ParameterFieldDefinition
For iParams As Integer = 0 To _
rptDoc.DataDefinition.ParameterFields.Count - 1
paramField =
rptDoc.DataDefinition.ParameterFields(iParams)
discreteVal.Value = params(iParams)
If discreteVal.Value IsNot Nothing Then
currVals.Add(discreteVal)
paramField.ApplyCurrentValues(currVals)
End If
Next
End Sub
If you are setting the parameters using this method, be sure
to remove the ReportDocument.Refresh code, otherwise it will set the report’s
metadata back to the original values and your new parameter values will be
lost.
With a few more tweaks to make your forms look and feel the
way your users expect, you can now distribute this utility and allow end users
to easily view currently populated reports that were created in the Crystal
Reports application or even that you created in the Crystal Report Designer in
.NET.