Colaboraciones en el Guille

Formas de conexión a una base de datos, utilizando Crystal Report .NET

 

Fecha: 18/Oct/2005 (17/10/05)
Autor: Lic. Giovanni Antonio Cuadra Reyes

AmericanCollege IT Manager

Email:   [email protected]
               [email protected]

          Niscasoft logo

!!!Tecnología de la Programación!!!
Managua, Nicaragua.

 


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:

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.Forms
Public 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 Class

Mé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


ir al índice principal del Guille