Pasando parámetros al informe en .NET con Crystal Reports.
Hace unas semanas publiqué el post Informe en .NET con Crystal Reports y base de datos MySQL, que se convirtió rápidamente en el post más visitado de este blog. También en el que más comentarios ha recibido, y precisamente de uno de ellos ha surgido este apéndice a dicho post.
Recordemos que en él enseñábamos cómo crear un informe con Crystal Reports utilizando un archivo XML y un DataTable (también servía un DataSet). En éste vamos a ver cómo podemos pasar parámetros al informe creado, por ejemplo para enviar el valor de un TextBox (aunque en mi ejemplo utilizaré una constante) y mostrarlo en el informe o bien utilizarlo para filtrar qué registros se tienen que mostrar y cuáles no.
Vamos a meternos pues en faena.
Partíamos de un par de tablas de MySQL y una vista que se había establecido así:
(
SELECT
blh_num AS BILL_NUMBER,
blh_dat AS BILL_DATE,
blh_cus AS BILL_CUSTOMER,
blp_pos AS LINE_NUMBER,
blp_art AS LINE_ARTICLE,
blp_pri AS LINE_UNITPRICE,
blp_qty AS LINE_UNITS,
blp_pri * blp_qty AS LINE_TOTALPRICE
FROM
blh_billheader LEFT JOIN blp_billposits ON blh_num = blp_num
WHERE
blh_num = 4
);
En la que por tanto filtrábamos los valores para obtener sólo los registros correspondientes a la factura número 4. Bien, vamos a cambiar eso para que ahora nuestro DataTable contenga todos los registros correspondientes a todas las facturas. La vista quedará pues ahora así:
(
SELECT
blh_num AS BILL_NUMBER,
blh_dat AS BILL_DATE,
blh_cus AS BILL_CUSTOMER,
blp_pos AS LINE_NUMBER,
blp_art AS LINE_ARTICLE,
blp_pri AS LINE_UNITPRICE,
blp_qty AS LINE_UNITS,
blp_pri * blp_qty AS LINE_TOTALPRICE
FROM
blh_billheader LEFT JOIN blp_billposits ON blh_num = blp_num
);
El resto de objetos siguen de momento igual. Esto es, el formulario frmMain y el reporte rptBill. No es preciso volver a generar el archivo XML para los cambios que vamos a hacer.
En el Explorador de campos hacemos click derecho en la opción Campos de parámetro para crear un nuevo parámetro. Lo creamos dándole un nombre (BillNumber) y un tipo de valor (Número) y aceptamos.
Si y sólo si tenemos algún interés en que este parámetro que posteriormente le enviaremos al informe aparezca en algún sitio de este informe, lo añadiremos a su área de impresión. En mi caso y sólo para que todo quede más claro, lo añado tal como se muestra en la imagen siguiente (el parámetro es el campo ?BillNumber):

Pero insisto en que lo importante ha sido crearlo. Arrastrarlo hasta el área de impresión del informe es absolutamente opcional.
En este ejemplo partimos de un DataTable con varios registros pertenecientes a distintas facturas y desearemos filtrar el reporte para que nos muestre sólo un determinado número de factura. Para ello tenemos pues que establecer este filtro.
Para ello, hacemos click derecho en cualquier punto del área de impresión del report y seleccionamos la opción Report - Fórmula de selección - Registro. En el editor que nos aparece seleccionamos los campos correspondientes para terminar creando la siguiente fórmula:
Guardamos el filtro y cerramos el editor.
Ya hemos creado un parámetro en el informe y hemos definido también un filtro basado en ese parámetro. Lo último que nos queda es pues informar el valor que deseamos que coja ese parámetro. En este caso lo haremos enviándoselo desde el formulario a través de una constante, pero como he dicho antes podríamos hacerlo tomando el valor, por ejemplo, de un TextBox o un DataGridView.
Para enviar el valor simplemente debemos añadir esta línea al código del formulario:
Con lo cual el código íntegro del formulario queda como sigue:
' Author: Albert Mata (www.albertmata.net)
' Date: 20081001
' Description: Form to show how to create a report using just an XML
' file, and how to send parameters to it.
'--------------------------------------------------------------------
Imports CrystalDecisions.CrystalReports.Engine
Public Class frmMain
'----------------------------------------------------------------
' Constants.
'----------------------------------------------------------------
Const BILL_NUMBER As Integer = 4
'----------------------------------------------------------------
' Creates XML file (just once) and creates and loads a report.
'----------------------------------------------------------------
Private Sub frmMain_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
'Creating XML file.
Dim RC As New clsReportCreator("zbl_bill2print")
'RC.CreateXMLFile("C:\")
'Creating report.
Dim RD As ReportDocument = New rptBill()
'Setting data source for report.
Dim DT As DataTable = RC.GetDataTable()
RD.SetDataSource(DT)
'Setting data source for possible subreports.
For Each SR As ReportDocument In RD.Subreports
If SR.Database.Tables.Count > 0 Then
SR.SetDataSource(DT)
End If
Next
'Setting recently created report must be shown in viewer.
Me.crvBill.ReportSource = RD
'Sending parameter to the report.
RD.SetParameterValue("BillNumber", BILL_NUMBER)
End Sub
End Class
Y esto es todo. A partir de aquí si ejecutamos la aplicación obtendremos el informe correspondiente.
Concretamente tal como está el código obtendremos lo siguiente:

Es decir, la factura número 4 porque hemos establecido el valor de la constante BILL_NUMBER a 4. Si cambiamos ese valor por un 3 y volvemos a ejecutar, obtendremos esto otro:

O sea, la factura número 3.
Vemos además que tanto en una como en la otra aparecen esos 4,00 y 3,00 fruto de que en el paso opcional de añadir el parámetro al área de impresión del informe, yo sí lo hice.
Tags: .NET, Crystal Reports, datatable, MySQL, parameter, report, view
Enero 5th, 2009 at 23:06
He intentado pasar parámetros a un informe de crystal reports y nunca he sido capaz de que funcionara correctamente, ya que tras usar el setParameter para asignar un valor, cuando voy a mostrar el informe me pide en un inputbox que introduzca el valor del parametro. Sabes a que se puede deber?
Enero 5th, 2009 at 23:48
No es SetParameter sino SetParameterValue. Y si lo utilizas correctamente pasándole tanto el nombre del parámetro exacto (que deberá existir previamente en el informe) como el valor que debe tomar... y hay concordancia en los tipos de datos, debería funcionar.
Te recomendaría que intentaras reproducir paso a paso el ejemplo del post anterior y de este propio, porque funciona perfectamente y así tal vez puedas ver qué te está fallando en tu caso.
Un saludo.
Enero 6th, 2009 at 00:31
Ya he encontrado el error. Es importante mantener el orden que se da en el ejemplo, ya que el siguiente código funciona:
Dim rptDocument As New informe
rptDocument.SetDataSource(getDSfiltrado)
Dim fr As New FormView
fr.crv.ReportSource = rptDocument
rptDocument.SetParameterValue("prueba", "hola")
fr.ShowDialog()
pero si el SetParameterValue lo ponemos antes no:
Dim rptDocument As New informe
rptDocument.SetDataSource(getDSfiltrado)
rptDocument.SetParameterValue("prueba", "hola")
Dim fr As New FormView
fr.crv.ReportSource = rptDocument
fr.ShowDialog()
En este último caso al mostrar el informe nos pide en un inputbox el valor del parametro.
Enero 6th, 2009 at 00:33
Muchas gracias por tu aportación, Santi.
Enero 17th, 2009 at 22:08
[...] Envio de Parametros ReportViewer No s
Mayo 12th, 2009 at 21:19
Hola,
Compañeros ya tengo un informe que se muestra y se imprime sin problemas, es una presentación de cuentas.
Sin embargo requiero que no solo se muestre el valor total de la cuenta en número sino también en letras, es decir 500.25 también imprimir quinientos veinticinco.
Esto lo hago en una función en vb y lo guardo en un textbox, el valor de este textbox necesito que se muestre en el informe para su impresión, me podrian ayudar por favor
Mayo 20th, 2009 at 21:14
Para pasar datos de un control a un reporte, tienes que crear una variable de tipo TextObject:
Dim ctrl as TextObject
ctrl = CType(rpt.ReportDefinition.ReportObjects("txtMontoLetras"), TextObject)
el "txtMontoLetras" se refiere al nombre de la caja de texto que está en el informe.
Espero me hayas entendido.
Saludos.
PD: Te puedo pasar un ejemplo por mail si deseas.
Julio 7th, 2009 at 15:44
Albert, sencillamente genial habia pensado que no se podia hacer, ahora me animo mas a seguir adelante con mi proyecto de enviarle parametros al crystal desde una interfaz personalizada
gracias y un saludo desde Manizales (Colombia)
Julio 7th, 2009 at 15:46
Gracias a ti por comentar, celebro que te haya sido útil...
Julio 10th, 2009 at 19:51
Hola: Me resulto muy interesante ver este ejemplo, Aun que mi caso es muy similar, pero con crystal reports 8.5, visual basic 6 y con una base de datos en access. Eso es lo que quisiera saber como enviar parametros al crystal reports desde una interfaz de visual basic 6 para visualizar un registro en especifico e imprimirlo.
Ojala me pudieses ayudar con este problema que me ha dado mucha lata. GRACIAS.
Julio 26th, 2009 at 00:23
Gracias por este material me sirvio mucho
sigan asi
Tus codigos son entendibles no como los de otras web