When a Crystal Report is designed with parameters, you need to supply those values in code before the report renders. If you leave it to the viewer to prompt the user at runtime, you lose control over formatting, validation, and the source of the value. Passing parameters programmatically keeps all of that in your hands.
This pattern comes up constantly in VB.NET Windows Forms applications that use Crystal Reports for invoices, term reports, date-filtered summaries, or any report that takes a runtime value.
Build a ParameterFields collection, populate it with one ParameterField per report parameter, and assign the collection to the viewer before it loads the report. Each parameter value is wrapped in a ParameterDiscreteValue, which represents a single concrete value as opposed to a range.
Dim paramFields As New CrystalDecisions.Shared.ParameterFields()
Dim paramField As New CrystalDecisions.Shared.ParameterField()
Dim discreteVal As New CrystalDecisions.Shared.ParameterDiscreteValue()
paramField.ParameterFieldName = "date"
discreteVal.Value = TermReport.PrintDate
paramField.CurrentValues.Add(discreteVal)
paramFields.Add(paramField)
CrystalReportViewer1.ParameterFieldInfo = paramFields
The string passed to ParameterFieldName must match the parameter name defined inside the Crystal Report exactly, including case. A mismatch will cause the viewer to fall back to prompting the user or throw a parameter missing exception at render time.
ParameterFieldInfo before setting ReportSource on the viewer, or before calling RefreshReport if the report is already loaded. Setting parameters after the report has already rendered has no effect until the next refresh.
The same pattern scales to any number of parameters. Create a new ParameterField and ParameterDiscreteValue pair for each one, add them all to the same ParameterFields collection, then assign the collection once at the end:
Dim paramFields As New CrystalDecisions.Shared.ParameterFields()
' First parameter: report date
Dim fieldDate As New CrystalDecisions.Shared.ParameterField()
Dim valDate As New CrystalDecisions.Shared.ParameterDiscreteValue()
fieldDate.ParameterFieldName = "date"
valDate.Value = TermReport.PrintDate
fieldDate.CurrentValues.Add(valDate)
paramFields.Add(fieldDate)
' Second parameter: student ID
Dim fieldId As New CrystalDecisions.Shared.ParameterField()
Dim valId As New CrystalDecisions.Shared.ParameterDiscreteValue()
fieldId.ParameterFieldName = "studentId"
valId.Value = TermReport.StudentId
fieldId.CurrentValues.Add(valId)
paramFields.Add(fieldId)
CrystalReportViewer1.ParameterFieldInfo = paramFields
ReportName property on each ParameterField to target the correct subreport. Leave ReportName as an empty string to target the main report.
- Any report that declares one or more parameters in the Crystal Reports designer and needs those values supplied from application data rather than user input.
- When the parameter value comes from a form field, a database query result, or a session variable that the user should not be able to override directly.
- When you need to suppress the Crystal Reports parameter prompt dialog entirely for a cleaner user experience.