Formas de conexión a una base de datos, utilizando Crystal Report .NET
Fecha: 18/Oct/2005 (17/10/05)
|
Introducción
Crystal Report ha sido uno de los diseñadores de reportes por excelencia más utilizado a nivel mundial, si no es el mejor diseñador de reportes, se encuentra entre los mejores. Pues su fácil uso y desempeño a logrado presentarse de forma consecutiva en versiones de Microsoft Visual Studio .NET en los recientes años.
La primera vez que utilice una versión de Crystal Report fue en Visual Basic 3.0, ya hace unos 10 años. Me sorprendió mucho solo el hecho que mostrara los datos mediante una presentación preliminar, el uso de formulas y una que otra utilidad prediseñada que tenía un único objetivo, el de simplificar un poco más algunas tareas de programación y al mismo tiempo enrobustecer el diseñador.
Recuerdo que aproximadamente en el año de 1997 en este mismo sitio escribí mi primer artículo basado en la propiedad SelectionFormula, un simple correo enviado a mi buen amigo el Guille donde explicaba el uso de dicha propiedad y de que forma se debería de implementar dentro de Visual Basic.
Ha pasado mucho tiempo desde que por primera vez utilice la versión de Crystal Report 4.5 Pro, después de esa versión llegaron nuevas generaciones de Crystal Report, tales como la 5.0 que la utilice muy poco tiempo por la sencilla razón que casi en seguida salieron la 6.0 y la 7.0. Pero la versión 7.0 fue sustancialmente mejorada tanto así que dure mucho tiempo en pasarme a la 8.5, ya que tenía algunas defectos en su forma de distribución y necesitaba descubrirlos antes de utilizarla, recuerdo que muchos se complicaron en esa versión, luego vino la 9.0 y actualmente la versión de .NET, luego la versión 10 y la versión 11 el cual quizás la estemos utilizando dentro de unos meses.
Este artículo esta basado en exponer dos formas de conexión para consultar e imprimir datos desde recursos compartidos o no compartidos.
Conectando una tabla de bases de datos mediante un Dataset con Crystal Rerport .NET
En el diseñador, aparece un el menú de proyectos la opción agregar un nuevo elemento. Se ejecuta esta opción y a continuación se visualiza una pantalla el cual solicita el nombre del componente a insertar en el proyecto. A continuación muestro el menú para ejecutar la opción :
La figura 1.0 Muestra la opción para insertar elementos nuevos a un proyecto.
La figura 2.0 Muestra la plantilla DataSet
Una vez insertado en el proyecto, será necesario crear una conexión con la base de datos y luego desde el explorador de servidores de la consola, se deberá arrastrar la tabla o las tablas, dependiendo de los datos desplegados en el reporte. A continuación muestro la forma de conexión a la base de datos y el arrastre de la tabla de ejemplo al DataSet.
La figura 3.0 Muestra el panel del explorador de servidores
La figura 4.0 Muestra las propiedades de conexión a la base de datos
La figura 5.0 Muestra la tabla dentro del Dataset
A como la figura anterior lo muestra, una vez hecha la conexión solo se requiere arrastrar y soltar la tabla sobre el panel del Dataset, el cual es el medio de diseño para el reporte. Una vez completado el proceso anterior se requiere insertar una plantilla de Crystal Report para elaborar el reporte. A continuación muestro el asistente para insertar la plantilla:
La figura 6.0 Muestra la plantilla para el reporte
Una vez insertado el archivo del reporte, lo único que falta por hacer es conectar el reporte con el Dataset del proyecto. A continuación muestro el proceso que se debe de realizar.
La figura 7.0 Muestra el mecanismo que se debe realizar para conectar el report con el objeto de conexión.
La figura 8.0 Muestra el Database Expert el cual permite seleccionar la forma de conexión.
Una vez aceptada la forma de conexión será necesario el paso final en la construcción del reporte, la cual es arrastrar y colocar los campos que se utilizaran dentro del mismo. A continuación muestro una figura con el proceso.
La figura 9.0 Muestra el reporte en forma de diseño.
Conectando una tabla de bases de datos directamente al Servidor
A diferencia de la forma anterior, con esta se hace la conexión directamente al servidor de la base de datos, no a un esquema como el caso del Dataset. Lo que aquí difiere es en dos cosas, la primera es que se tiene que utilizar del Database Expert de Crystal Report, el tipo de conexión OLE DB ADO y la segunda cosa diferente es la forma de ejecutar el reporte al pasar toda su información de conexión. A continuación muestro los pasos para conectar al servidor, en cuanto al proceso del diseño del reporte son los mismos que el anterior.
La figura 10 Muestra el tipo de conexión seleccionada.
Implementando una solución con Visual Basic .NET
A continuación muestro un ejemplo muy sencillo utilizando dos tipos de reportes, el primero conectado a un origen de una esquema de datos y el segundo directamente al servidor en donde se encuentra la base de datos. Los siguientes requisitos serán necesarios:
- Microsoft Visual Basic .NET 2003
- Microsoft Windows XP o superior
- Microsoft SQL Server 2000
- Computador Pentium o superior
- Memoria RAM 128 o superior
- Monitor VGA de ‘’15 o superior
La clase clsPrintReport contiene tres métodos para poder ejecutar un reporte de Crystal Report, cada uno con sus diferencias, ventajas, desventajas, así como también sus similitudes. A continuación muestro el código fuente:
Imports CrystalDecisions.ReportSource Imports CrystalDecisions.Shared Imports CrystalDecisions.CrystalReports.Engine Imports CrystalDecisions.CrystalReports Imports CrystalDecisions.Windows Imports CrystalDecisions.Windows.Forms Imports System.Windows.FormsPublic Class Report Implements IPrintReport Dim DidPreviouslyConnect As Boolean = False Public Sub PrintPreview(ByVal FileReport As String, ByVal DataSource As System.Data.DataSet, _ Optional ByVal Filter As String = "") Implements IPrintReport.PrintPreview Dim frmCRNet As New frmCRNET Dim frmStatusMessage As New frmStatus Dim IsConnecting As Boolean = True Dim crNicasoftStandarReport As New ReportDocument If Not DidPreviouslyConnect Then frmStatusMessage.Show("Estableciendo conexión...") End If While IsConnecting Try Cursor.Current = Cursors.WaitCursor With frmCRNet With crNicasoftStandarReport .Load(FileReport) .SetDataSource(DataSource) End With .crWinNet.ReportSource = crNicasoftStandarReport If Not Filter = "" Then .crWinNet.SelectionFormula = Filter End If .crWinNet.Refresh() .Show() IsConnecting = False DidPreviouslyConnect = True frmStatusMessage.Close() End With Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.Critical) Cursor.Current = Cursors.Default frmStatusMessage.Close() frmCRNet.Close() Exit While Exit Try Exit Sub End Try End While End Sub Public Sub Print(ByVal FileReport As String, ByVal DataSource As System.Data.DataSet, _ Optional ByVal Filter As String = "") Implements IPrintReport.Print Dim frmCRNet As New frmCRNET Dim frmStatusMessage As New frmStatus Dim IsConnecting As Boolean = True Dim crNicasoftStandarReport As New ReportDocument If Not DidPreviouslyConnect Then frmStatusMessage.Show("Estableciendo conexión...") End If While IsConnecting Try Cursor.Current = Cursors.WaitCursor With frmCRNet With crNicasoftStandarReport .Load(FileReport) .SetDataSource(DataSource) End With .crWinNet.ReportSource = crNicasoftStandarReport If Not Filter = "" Then .crWinNet.SelectionFormula = Filter End If .crWinNet.Refresh() .crWinNet.PrintReport() IsConnecting = False DidPreviouslyConnect = True frmStatusMessage.Close() End With Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.Critical) Cursor.Current = Cursors.Default frmStatusMessage.Close() frmCRNet.Close() Exit While Exit Try Exit Sub End Try End While End Sub Public Sub PrintLogon(ByVal FileReport As String, ByVal Username As String, ByVal Password As String, _ ByVal Servername As String, Optional ByVal Filter As String = "") Implements IPrintReport.PrintLogon Dim frmCRNet As New frmCRNET Dim frmStatusMessage As New frmStatus Dim IsConnecting As Boolean = True Dim crNicasoftStandarReport As New ReportDocument Dim crSections As Sections Dim crSection As Section Dim crReportObjects As ReportObjects Dim crReportObject As ReportObject Dim crSubreportObject As SubreportObject Dim crSubreportDocument As ReportDocument Dim crDatabase As Database Dim crTables As Tables Dim crTable As Table Dim crTableLogOnInfo As TableLogOnInfo Dim crConnectioninfo As ConnectionInfo If Not DidPreviouslyConnect Then frmStatusMessage.Show("Estableciendo conexión...") End If While IsConnecting Try Cursor.Current = Cursors.WaitCursor crConnectioninfo = New ConnectionInfo With crConnectioninfo .ServerName = Servername .UserID = Username .Password = Password End With With frmCRNet crNicasoftStandarReport.Load(FileReport) crDatabase = crNicasoftStandarReport.Database crTables = crDatabase.Tables For Each crTable In crTables crTableLogOnInfo = crTable.LogOnInfo crTableLogOnInfo.ConnectionInfo = crConnectioninfo crTable.ApplyLogOnInfo(crTableLogOnInfo) Next crSections = crNicasoftStandarReport.ReportDefinition.Sections For Each crSection In crSections crReportObjects = crSection.ReportObjects For Each crReportObject In crReportObjects If crReportObject.Kind = ReportObjectKind.SubreportObject Then crSubreportObject = CType(crReportObject, SubreportObject) crSubreportDocument = _ crSubreportObject.OpenSubreport(crSubreportObject.SubreportName) crDatabase = crSubreportDocument.Database crTables = crDatabase.Tables For Each crTable In crTables With crConnectioninfo .ServerName = Servername .UserID = Username .Password = Password End With crTableLogOnInfo = crTable.LogOnInfo crTableLogOnInfo.ConnectionInfo = crConnectioninfo crTable.ApplyLogOnInfo(crTableLogOnInfo) Next End If Next Next .crWinNet.ReportSource = crNicasoftStandarReport If Not Filter = "" Then .crWinNet.SelectionFormula = Filter End If .crWinNet.Refresh() .Show() IsConnecting = False DidPreviouslyConnect = True frmStatusMessage.Close() End With Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.Critical) Cursor.Current = Cursors.Default frmStatusMessage.Close() frmCRNet.Close() Exit While Exit Try Exit Sub End Try End While End Sub End ClassMétodo PrintPreview: Este método permite conectarse a bases de datos mediante orígenes de tipo Dataset. Permite mostrar el reporte antes de imprimir.
Método Print: Este método permite conectarse a bases de datos mediante orígenes de tipo Dataset. Difiere con el método anterior en que este no muestra el reporte para una presentación preliminar.
Método PrintLogon: Este método permite conectarse a bases de datos mediante orígenes de tipo OLE DB ADO, directamente al servidor donde reside la base de datos.
Cada método de esta clase maneja interfaces, así que si se modifica cualquiera de estos métodos será necesario actualizar antes el archivo IPrintReport.
A continuación muestro el código de donde se invocan dos de tres métodos:
Dim OpenReport As New Report
Dim User As String = "sa"
Dim Password As String = ""
Dim Servername As String = "localhost"
Dim Filter As String = ""
Dim Filename1 As String = "C:\VS2003\CRNETconnect\ConnectioCRNET\crEmpleados_Dataset.rpt"
Dim Filename2 As String = "C:\VS2003\CRNETconnect\ConnectioCRNET\crEmpleados_ADOServer.rpt"
Dim datEmpleados As New DataSet
Private Sub MenuItem4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem4.Click
Me.Close()
End Sub
Private Sub MenuItem2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem2.Click
OpenReport.PrintPreview(Filename1, datEmpleados, Filter)
End Sub
Private Sub MenuItem3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem3.Click
OpenReport.PrintLogon(Filename2, User, Password, Servername, Filter)
End Sub
Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.SqlCon.Open()
Me.DA_Empleados.Fill(Me.datEmpleados, "Employees")
Me.SqlCon.Close()
End Sub
El resto del código se encuentra en el proyecto, aquí solo expongo el más significativo, como parte del código en la información de conexión declaro el nombre del servidor como localhost, para que pueda ser ejecutado sin cambiar el nombre del servidor dentro del objeto de conexión Sqlcon. La localización de los archivos de cada reporte se encuentra declarada bajo el directorio donde fue creado el proyecto, así que al descomprimir el proyecto si no se crea el mismo Path del proyecto será necesario reconfigurar eso en las variables. En cuanto el servidor de base de datos donde apuntan las tablas, es reemplazado dinámicamente en el momento que se pasa a los métodos la información requerida por la clase.
Conclusiones
Las herramientas modernas de desarrollador han permitido mayores logros en la industria de la informática. Cada uno de estos logros son potencializados y representados al usuario final como una solución que satisfaga a las organizaciones modernas con intencion de modernizarlas en el futuro.
En cada coyuntura, la tecnología de información moderna se ha destacado en proporcionar mayores soluciones. Y cada solución ha permitido escalar un nivel más en el mundo de la informática.
Giovanni Cuadra.
Espacios de nombres usados en el código de este artículo:
CrystalDecisions.ReportSource
CrystalDecisions.Shared
CrystalDecisions.CrystalReports.Engine
CrystalDecisions.CrystalReports
CrystalDecisions.Windows
CrystalDecisions.Windows.Forms
System.Windows.Forms
Fichero con el código de ejemplo: gcuadraCRNET.zip - 101 KB