Colabora VB6

¿Cómo usar Report Manager con VB 6 (2º Parte)?

[Gestor de informes GNU en tus aplicaciones VB 6]

Fecha: 20/Dic/2006 (18 Diciembre 2006)
Autor: Brian Plano Abad - [email protected]
Redactado por: J.Jesús Daryanani - GOPI ([email protected]

Introducción

Inicialmente comentar que esta segunda parte ha surgido a raíz de una consulta enviada por el colega Brian Plano. De hecho es de justicia decir que prácticamente todo lo expuesto aquí es obra suya.

¿ Cómo surgió esta segunda parte ?

No era la primera vez que me consultaban como definir la ruta de la Base de datos en tiempo de ejecución y no en tiempo de diseño. En mi ejemplo creaba los informes suponiendo a priori la ubicación de la base de datos. La solución pasa por definir un DSN, preferiblemente de sistema y usarlo en el diseño de los reportes.

Solución propuesta por Brian: 

A continuación transcribo literalmente, con su autorización, parte del contenido de su email:

Primero al entrar en la aplicación creo un DSN conectando a la base de datos del cliente, este es el código:

Utilizo la API “SQLConfigDataSource” para esta acción.

MOD_DSN (crea la conexión)

Option Explicit

' Constantes

Private Const ODBC_ADD_DSN = 1 ' Nuevo DSN

Private Const ODBC_CONFIG_DSN = 2 ' Modificar DSN

Private Const ODBC_REMOVE_DSN = 3 ' Eliminar DSN

Private Const ODBC_ADD_SYS_DSN = 4 ' Nuevo DSN de sistema

Private Const ODBC_CONFIG_SYS_DSN = 5 ' Modificar DSN de sistema

Private Const ODBC_REMOVE_SYS_DSN = 6 ' Eliminar DSN de sistema

Private Const vbAPINull As Long = 0 ' Null Pointer

Private Const SQL_SUCCESS As Long = 0

Private Const SQL_FETCH_NEXT As Long = 1

' Declaración de funciones de API

Private Declare Function SQLConfigDataSource Lib "ODBCCP32.DLL" (ByVal hwndParent As Long, ByVal fRequest As Long, ByVal lpszDriver As String, ByVal lpszAttributes As String) As Long

Private Declare Function SQLDataSources Lib "ODBC32.DLL" (ByVal henv As Long, ByVal fDirection As Integer, ByVal szDSN As String, ByVal cbDSNMax As Integer, pcbDSN As Integer, ByVal szDescription As String, ByVal cbDescriptionMax As Integer, pcbDescription As Integer) As Integer

Private Declare Function SQLAllocEnv Lib "ODBC32.DLL" (Env As Long) As Integer

‘Elimina un DSN del sistema.

Function BorrarDSN(sDSN As String, sDriver As String) As Boolean

Dim sAtributos As String

' Borramos el DSN (En vez de vbAPINull, empleamos el hwnd del formulario)

If ExisteDSN(sDSN) Then

sAtributos = "DSN=" & sDSN & Chr(0)

BorrarDSN = CBool(SQLConfigDataSource(vbAPINull, ODBC_REMOVE_SYS_DSN, sDriver, sAtributos))

Else

MsgBox ExIdioma("ModDSN_Contr1")

BorrarDSN = False

End If

End Function

 

 

‘Comprueba si existe un DSN en el sistema.

Function ExisteDSN(sDSN As String) As Boolean

Dim I As Integer, j As Integer

Dim sDSNItem As String * 1024

Dim sDRVItem As String * 1024

Dim sDSNActual As String

Dim sDRV As String

Dim iDSNLen As Integer

Dim iDRVLen As Integer

Dim lHenv As Long 'controlador del entorno

Dim DSNLISTA(100)

ExisteDSN = False

For j = 1 To 52

DSNLISTA(j) = ""

Next j

j = 1

If SQLAllocEnv(lHenv) <> -1 Then

Do Until I <> SQL_SUCCESS

sDSNItem = Space(1024)

sDRVItem = Space(1024)

I = SQLDataSources(lHenv, SQL_FETCH_NEXT, sDSNItem, 1024, iDSNLen, sDRVItem, 1024, iDRVLen)

sDSNActual = VBA.Left(sDSNItem, iDSNLen)

sDRV = VBA.Left(sDRVItem, iDRVLen)

If sDSN <> Space(iDSNLen) Then

DSNLISTA(j) = sDSN

If UCase(sDSN) = UCase(sDSNActual) Then

ExisteDSN = True

Exit Do

End If

End If

Loop

End If

End Function

 

 

‘Crea un DSN del sistema.

Function CrearDSN(sDSN As String, sDriver As String, sAtributos As String) As Boolean

' Creamos el DSN (En vez de vbAPINull, empleamos el hwnd del formulario)

CrearDSN = CBool(SQLConfigDataSource(vbAPINull, ODBC_ADD_SYS_DSN, sDriver, sAtributos))

End Function

 

 

‘Crea un DSN MySQL con los atributos bien seteados.

Function MySQLCrearDSN(sDSN As String) As Boolean

Dim sDriver As String

Dim sAtributos As String

sDriver = "MySQL ODBC 3.51 Driver"

sAtributos = "DSN=" & sDSN & Chr(0)

sAtributos = sAtributos & "SERVER=" & StrServer & Chr(0)

sAtributos = sAtributos & "PORT=3306" & Chr(0)

sAtributos = sAtributos & "DATABASE=" & StrBD & Chr(0)

sAtributos = sAtributos & "USER=" & Usu & Chr(0)

sAtributos = sAtributos & "PASSWORD=" & Contra & Chr(0)

sAtributos = sAtributos & "OPTION=3" & Chr(0)

' Si queremos quitar la base de datos, debemos borrarlo antes

If ExisteDSN(sDSN) Then

Call BorrarDSN(sDSN, sDriver)

End If

MySQLCrearDSN = CrearDSN(sDSN, sDriver, sAtributos)

End Function

Nota que en la conexión del DSN he utilizado las variables GLOBALES para declarar el servidor, base de datos, usuario y contraseña, estas hay que sustituirlas por las que cada uno tenga.

En el formulario de carga de la aplicación coloco el siguiente código:

FrmLogin (Damos de alta la conexión)

        'Creamos el DSN para las conexiones con el gestor de reportes.

        If ExisteDSN("DSNTemp") = True Then

            'Si existe lo eliminamos previamente.

            If BorrarDSN("DSNTemp ", "MySQL ODBC 3.51 Driver") = False Then

                MsgBox “Fallo en la conexión”, cAceptar + cvbCritical

                End

            End If

        End If

       

        'Creamos el nuevo DSN.

        If MySQLCrearDSN("DSNTemp ") = False Then

            MsgBox “Fallo en la conexión”, cAceptar + cvbCritical

            End

        End If

Ahora llega el punto clave, cuando diseñamos el reporte, debemos tener creada esta conexión DSN en nuestro sistema, de esta manera, la aplicación cuando cree la de nuestro usuario, usará los datos que el programa ha proporcionado para la creación de esta conexión, de esta manera tu puedes diseñar los reportes en tu PC y asegurarte de que tu usuario final siempre verá los datos de su base de datos utilizando el mismo nombre de conexión.

Espero haberme explicado bien, ahora te paso la creación de la conexión ADO para MySQL en VB6:

Conexión ADO MySQL en VB6

Public Bd As ADODB.Connection '--> Declaramos la variable de Base de datos.

Public RM1 As ADODB.Recordset '--> Declaramos el Recordset.

Public Const DirServer = "localhost" 'Constante con la IP o el DNS del servidor.

Public Const Usu = “Usuario”

Public Const Contra = “Contraseña”

Public Const StrBD = “Base_de_datos”

 

'CONECTA CON LA BASE DE DATOS DEL CLIENTE.

'1) **************************************************************

Function ConecCliente()

    Set Bd = New ADODB.Connection

    Set RM1 = New ADODB.Recordset

    Bd.CursorLocation = adUseClient

    Bd.ConnectionString = "DRIVER={MySQL ODBC 3.51 Driver};SERVER=" & StrServer & ";PORT=3306;DATABASE=" & StrBD & "; USER=" & Usu & ";PASSWORD=" & Contra & ";OPTION=3;"

End Function

'1) **************************************************************

Una vez declaradas estas instrucciones puedes trabajar con el recordset RM1 de manera normal y corriente, es importante remarcar que para poder trabajar de esta manera se tiene que tener instalado en la máquina el conector ODBC de MySQL 3.51, lo puedes descargar de aquí http://dev.mysql.com/get/Downloads/MyODBC3/mysql-connector-odbc-3.51.12-win32.msi/from/pick

Lo demás es historia, se puede eliminar el DSN al salir del programa, o que lo elimine cuando entra como hago yo, sobretodo eliminar el conector y el recordset al final de la aplicación.

Espero haberte ayudado, creo que ya tienes una buena manera para publicarlo en la web, si puedes hazme referencia que me haría mucha ilusión, gracias por tu genial idea del DSN!!

Un abrazo!

Brian Plano Abad

Dpto. Soporte Técnico

[email protected]

 

Destacar que este ejemplo concreto tira de una base de datos MySQL. Estoy adaptando esta idea a un tema que tengo entre manos que trabaja contra Postgress. Mientras tengamos el ODBC podremos adaptarlo a nuestras necesidades.

Conclusión.

Sólo agradecer al colega Brian por su aportación y como no, al Guille por su dedicación y esfuerzo en el mantenimiento de esta página.

Como estamos cerca de Navidad, Felicidades para todos......

Saludos...

J. Jesús Daryanani

[email protected]

 



ir al índice principal del Guille