Archivo de Etiquetas de 'view'

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.

Paso 1. Recopilatorio de lo que teníamos.

Partíamos de un par de tablas de MySQL y una vista que se había establecido así:

CREATE VIEW zbl_bill2print 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í:

CREATE VIEW zbl_bill2print 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.

Paso 2. Añadir parámetro en el informe rptBill.

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.

Paso 3. Establecer el filtro para el informe.

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:

{zbl_bill2print.BILL_NUMBER} = {?BillNumber}

Guardamos el filtro y cerramos el editor.

Paso 4. Enviar el valor del parámetro desde el formulario.

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:

RD.SetParameterValue(”BillNumber”, BILL_NUMBER)

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.

Instrucciones menos habituales en MySQL (1a parte).

Utilizando la base de datos MySQL como acostumbro, constantemente estoy lidiando con las sintaxis más habituales para crear y modificar tablas, funciones, vistas y demás. No obstante, hay también por ahí un conjunto de instrucciones que alguna vez he utilizado y que solía tener que googlear porque nunca las recordaba desde la vez anterior. Hasta que me decidí a ir anotándolas, por tontas y breves que fueran. Y ahora, ya que estamos, me ha parecido buena idea compartirlas por si a alguien le sirven de algo.

Ver el código que en su día utilizamos para crear una vista.

Si por ejemplo hacemos un…

DESCRIBE tbl_tablenamex;

…sobre una tabla o una vista, nos devuelve la estructura de esa tabla o vista, con sus campos y tipos de datos y demás información básica. No obstante, en ocasiones con las vistas me interesa ver de una manera rápida con qué sintaxis exacta la creé (de dónde saqué los campos, cómo enlacé las tablas, etc.). Normalmente tengo esa información guardada en archivos de texto, ya que raramente creo una vista directamente en consola, sino que más bien suelo hacerlo a través de archivos planos. No obstante me resulta más rápido verlo directamente en la consola que tener que ir a buscar el archivo. Para ello me valgo de…

SHOW CREATE VIEW viw_viewnamexx;

…y obtengo, aunque de un modo no muy agradable de ver, la sintaxis que utilicé para crear la vista en su momento.

Reiniciar el contador autonumérico de una tabla.

A menudo utilizo campos autonuméricos en mis tablas. Aunque tienen algún inconveniente, si se utilizan únicamente a modo de campo identificador para uso fundamentalmente interno, suelen aportar mayores ventajas que inconvenientes presentan. ¿Pero cómo reiniciamos el contador autonumérico después de haber estado trasteando con la tabla? Muy fácil, en dos pasos. El primero es asegurarnos que la tabla está totalmente vacía de registros. El segundo consiste en aplicar…

ALTER TABLE tbl_tablenamex AUTO_INCREMENT = 1;

…y el contador habrá quedado convenientemente reseteado. Si queremos que se resetee pero que no comience de nuevo por el 1 sino por ejemplo por el 1001, también se lo podemos indicar con esta misma instrucción.

Listar todas las tablas en una base de datos.

En principio para hacer esto nos podemos valer de un simple…

SHOW TABLES;

…pero esto solo nos listará las tablas sin añadir mayor información, cosa que la mayor parte de las veces nos puede ser más que suficiente. Sin embargo si queremos obtener más información podemos utilizar…

SELECT *
FROM information_schema.tables
WHERE table_schema = 'nameofddbb';

…y obtendremos no solo el nombre sino también si se trata de una tabla o vista, qué motor utiliza (InnoDB, MyISAM…), el número de registros, la fecha de creación, aspectos sobre el tamaño, etc.

Listar todos los campos en una tabla.

Del mismo modo, para los campos podemos hacer como hemos dicho antes un…

DESCRIBE tbl_tablenamex;

…pero si queremos un poco más de información también podemos recurrir a…

SELECT *
FROM information_schema.columns
WHERE table_name = 'tbl_tablenamex';

…y como ocurría con las tablas obtendremos algo más de información.

Obtener información sobre rutinas.

Si lo que queremos es obtener información sobre funciones o procedimientos almacenados en una base de datos (incluyendo el código fuente con el que se crearon), podemos utilizar…

SELECT *
FROM information_schema.routines
WHERE routine_schema = 'nameofddbb';

Obtener información sobre vistas (otro método).

Si de lo que queremos obtener información más detallada (incluyendo nuevamente el código utilizado en la generación) es una vista, podemos utilizar…

SELECT *
FROM information_schema.views
WHERE table_schema = 'nameofddbb';

Obtener información sobre triggers (disparadores).

Y si lo que queremos es obtener información más detallada sobre disparadores o triggers (también incluyendo el código con el que se han generado), podemos utilizar…

SELECT *
FROM information_schema.triggers
WHERE trigger_schema = 'nameofddbb';

Copiar una tabla y opcionalmente rellenarla.

Si deseamos crear una copia de una tabla en la misma o en otra base de datos, podemos utilizar primero esta instrucción para copiar la estructura…

CREATE TABLE tbl_targettabl LIKE nameofddbb.tbl_sourcetabl;

…y nos creará una tabla destino igual que la tabla origen, solo que sin datos dentro. Para copiar a continuación todos los datos nos bastará con…

INSERT INTO tbl_targettabl
SELECT * FROM nameofddbb.tbl_sourcetabl;

De hecho, en caso de querer copiar tanto estructura como datos, también podríamos haberlo hecho en un solo paso con…

CREATE TABLE tbl_targettabl
SELECT * FROM nameofddbb.tbl_sourcetabl;

…pero para mí gusto, este método presenta el inconveniente de que si la tabla contiene claves principales no se trasladan a la copia, por lo cual yo prefiero siempre el método en dos pasos.

Y lo de añadir nameofddbb. antes del nombre de la tabla está claro que sólo será preciso cuando estemos operando con dos bases de datos distintas (si solo trabajamos con una no es preciso añadirlo).

Esto es todo por ahora. Seguro que me dejo más instrucciones de esas poco frecuentes que a veces necesitamos, así que titulo intencionadamente el post con lo de 1a parte en previsión de que más adelante pueda haber otras.




Creative Commons License
El blog de Albert Mata by Albert Mata is licensed under a Creative Commons Reconocimiento-Compartir bajo la misma licencia 2.5 España License.