8/29/2011

Acceso nativo a MySQL Server con VB.Net usando el driver Connector Net



Mostramos algunas de las ventajas e inconvenientes de usar acceso nativo a motores de bases de datos desde aplicaciones Visual Basic .Net. Explicamos los requisitos necesarios para desarrollar una aplicación en Microsoft Visual Basic .Net 2010 que acceda a un servidor de MySQL Server de forma nativa, sin intermediarios (ni ODBC, ni OLE DB). Listamos el código fuente de la aplicación AjpdSoft Acceso nativo MySQL VB.Net.


Acceso nativo vs Acceso ODBC / OLE DB en MySQL

Existen varios métodos para conexión de una aplicación a un motor de bases de datos. Estos métodos pueden variar en función de muchos valores como el sistema operativo, el motor de base de datos o el lenguaje de programación usado para desarrollar la aplicación. A continuación exponemos algunas de las ventajas y desventajas de usar acceso nativo y acceso ODBC u OLE DB.

Ventajas de usar acceso nativo a motores de bases de datos

En general, usar el acceso nativo a un motor de bases de datos mejora el rendimiento, puesto que la conexión entre nuestra aplicación y el motor de base de datos es directa y no necesita de intermediarios.
Otra ventaja de usar acceso nativo, normalmente, es que se evita tener que instalar software de terceros, pues normalmente usaremos una librería proporcionada por el motor de base de datos que será la que contenga las clases o API necesaria para el acceso al motor. En cambio, si usáramos acceso ODBC u otro no nativo (OLE DB), tal vez se requiera de la instalación de software adicional. Por ejemplo, para el caso de acceso nativo a MySQL Server usando Visual Basic .Net y el driver Connector/Net, una vez compilado y generado el ejecutable de nuestra aplicación, sólo necesitará el fichero mysql.data.dll en la carpeta del ejecutable para el acceso a MySQL Server.
El acceso nativo a los motores de bases de datos suele ser muy usado para desarrollar aplicaciones con motores embebidos que no requieren de ningún tipo de instalación, de forma que el usuario realiza la descarga de nuestra aplicación y no necesita de instalaciones adicionales, es suficiente con ejecutar el fichero de la aplicación. Muchos de los motores actuales de bases de datos incluyen una versión embebida de su base de datos, que no requiere de instalación en un servidor.
Otra de las ventajas de usar acceso nativo a un motor de base de datos desde nuestra aplicación es que podemos usar todas las caracterísitcas específicas del motor, lo que aumentará las posibilidades de nuestra aplicación.

Inconvenientes de usar acceso nativo a motores de bases de datos

El principal inconveniente es que la aplicación que desarrollemos con acceso nativo al motor de base de datos, por ejemplo a MySQL, nos obligará a usar siempre ese motor de bases de datos. Nuestra aplicación no podrá usar otro motor de base de datos distinto del driver nativo usado para la conexión. Si usamos Connector/Net de MySQL Server para acceso nativo, nuestra aplicación no podrá usar otros motores como Oracle, PostgreSQL, SQLite, Access o SQL Server. Por lo tanto haremos dependiente la aplicación del motor de base de datos.
Por lo tanto perderemos la versatilidad de desarrollar una aplicación que sea independiente del motor de base de datos, por lo que restringiremos considerablemente le uso de la aplicación.

Conclusión acceso nativo vs ODBC ó OLE DB

El usar acceso nativo u otro tipo de acceso a un motor de bases de datos dependerá de las funcionalidades y características de la aplicación que queramos desarrollar, así como del uso y distribución que se le quiera dar a ésta.
Por ejemplo, si vamos a desarrollar una aplicación a medida para una empresa que siempre ha usado el motor de bases de datos MySQL Server y no hay previsión de cambio, tal vez sea recomendable usar acceso nativo, mejorando el rendimiento. En cambio, si queremos desarrollar una aplicación estándar para que sirva al mayor número de usuarios posible, para distribuirla en nuestro sitio web, sería recomendable usar acceso no nativo (ODBC, OLE DB) para hacer la aplicación independiente del motor de base de datos usado y permitir al usuario elegir el que más se ajuste as us necesidades.
En definitiva, el acceso nativo mejora el rendimiento pero limita la aplicación a un motor de base de datos concreto. Es recomendable que el desarrollador conozca a la perfección tanto los distintos métodos de conexión para el motor de base de datos elegido como las necesidades de la empresa o usuarios finales de la aplicación. Una vez adquiridos estos conocimientos podrá elegir el método que mejor se adapte a las necesidades.

Requisitos para desarrollar aplicación con acceso a MySQL nativo usando Visual Basic .Net y driver Connector/Net

A continuación indicamos los requisitos necesarios para desarrollar una aplicación, usando el IDE de desarrollo Microsoft Visual Basic .Net, que acceda de forma nativa (directa sin intermediarios) al motor de base de datos gratuito MySQL Server.
  • Suite de desarrollo Microsoft Visual Studio .Net 2010: en el siguiente enlace explicamos cómo instalar este entorno de desarrollo de aplicaciones .Net:
  • Driver Connector/Net de MySQL: necesitaremos las librerías proporcionadas por MySQL para acceso nativo desde .Net, disponibles en el sitio web oficial de MySQL, en la URL:
    http://dev.mysql.com/downloads/connector/net
    En nuestro caso descargaremos la versión 6.4.3 y la plataforma (Select Platform) ".NET & Mono":
Requisitos para desarrollar aplicación con acceso a MySQL nativo usando Visual Basic .Net y driver Connector/Net
La ventana de ".NET & Mono" es que no requiere de instalación, descargaremos un fichero comprimido que descomprimiremos:
Requisitos para desarrollar aplicación con acceso a MySQL nativo usando Visual Basic .Net y driver Connector/Net

Desarrollar aplicación VB.Net con acceso nativo a MySQL Server mediante Connector/Net

Para crear una aplicación en Microsoft Visual Basic .Net 2010 con acceso nativo a MySQL Server, pulsaremos en el menú "Archivo" - "Nuevo proyecto":
Desarrollar aplicación VB.Net con acceso nativo a MySQL Server mediante Connector/Net
En "Plantillas instaladas" desplegaremos "Visual Basic" y seleccionaremos "Windows". En la parte derecha, seleccionaremos .Net Framework 4 y "Aplicación de Windows Forms". En la parte inferior introduciremos el nombre para el nuevo proyecto VB.Net, por ejemplo "AjpdSoftAccesoNativoMySQLVB":
Desarrollar aplicación VB.Net con acceso nativo a MySQL Server mediante Connector/Net
Deberemos añadir una referencia a MySQL Connector/Net, para ello en el "Explorador de soluciones" (o bien desde el menú "Proyecto" - "Agregar referencia") pulsaremos con el botón derecho del ratón sobre la solución y seleccionaremos "Agregar referencia":
Desarrollar aplicación VB.Net con acceso nativo a MySQL Server mediante Connector/Net
Seleccionaremos la pestaña "Examinar" y buscaremos el fichero "mysql.data.dll" dentro de la carpeta "v4" de la descarga del driver Connector/Net de MySQL. Seleccionaremos el fichero "mysql.data.dll" y pulsaremos "Aceptar":
Desarrollar aplicación VB.Net con acceso nativo a MySQL Server mediante Connector/Net
Pulsando en la pestaña de ver código fuente del formulario principal (o con la tecla F7), desde el código fuente, al principio, añadiremos el siguiente import:
Imports MySQL.Data.MySqlClient
Desarrollar aplicación VB.Net con acceso nativo a MySQL Server mediante Connector/Net
Con estos pasos tendremos disponible el API para acceso nativo a MySQL Server desde Visual Basic .Net.
Añadiremos los componentes visuales y no visuales al formulario principal de la aplicación:
  • TextBox: para introducir el servidor de MySQL Server, el puerto, el usuario, la contraseña.
  • ComboBox: desplegable donde se mostrarán los esquemas o bases de datos del servidor MySQL Server al que nos hemos conectado.
  • TextBox con Multiline=True: para introducir consulta SQL que se ejecutará.
  • RadioButton: para elegir entre consulta SQL que devuelve registros (SELECT) o consulta SQL que no devuelve registros (INSERT, DELETE, UPDATE, DROP, CREATE, ALTER).
  • Button: para conectar con servidor, para abrir base de datos y para ejecutar la consulta SQL introducida.
  • DataGridView: para mostrar los registros resultantes de una consulta SQLL.
  • StatusStrip: barra de estado para mostrar algunos datos adicionales (número de tablas de la base de datos elegida, número de registros de la consulta SQL ejecutada, usuario, servidor y base de datos a la que estamos conectados.
  • ToolTip: para mostrar cuadro de ayuda rápida de los elementos del formulario.
Desarrollar aplicación VB.Net con acceso nativo a MySQL Server mediante Connector/Net
A continuación mostramos el código fuente más importante de la aplicación:
  • Por un lado declararemos una variable de tipo MySqlConnection al principio de la clase del formulario. Será la que contenga la conexión con el servidor MySQL Server y será usada en los distintos métodos que requieran de conexión:
Friend conexion As MySqlConnection
  • Función conectarServidorMySQL para conectar con un servidor MySQL Server de forma nativa, esta función usará la variable declarada al principio de la clase, llamada conexion, la inicializará con "New MySqlConnection" y establecerá los valores de conexión con "ConnectionString". Una vez establecidos realizará la conexión con el método "Open":
    Private Sub conectarServidorMySQL()         Try             conexion = New MySqlConnection()             conexion.ConnectionString =                 "server=" & txtServidor.Text & ";" &                 "user id=" & txtUsuario.Text & ";" &                 "password=" & txtContrasena.Text & ";" &                 "port=" & txtPuerto.Text & ";" &                 "database=" & lsBD.Text & ";"             conexion.Open()             If lsBD.Text <> "" Then                 bePanelNumTablas.Text = CStr(numeroTablas())             End If             bePanel2.Text = "Conectado a servidor " &                 txtServidor.Text         Catch ex As Exception             MsgBox("Error al conectar al servidor MySQL " &                    vbCrLf & vbCrLf & ex.Message,                    MsgBoxStyle.OkOnly + MsgBoxStyle.Critical)         End Try     End Sub
  • Función numeroRegistrosConsulta que obtiene el número de registros de una consulta dada en una variable de tipo MySqlDataReader. Pasándole como parámetro un MySqlDataReader, lo recorrerá y obtendrá el número de registros:
    Private Function numeroRegistrosConsulta( _                 ByVal dr As MySqlDataReader) As Integer         Dim numeroRegistros As Integer = 0         Do While dr.Read             numeroRegistros = numeroRegistros + 1         Loop         numeroRegistrosConsulta = numeroRegistros     End Function
  • Función numeroTablas que obtiene el número de tablas de un esquema (base de datos) de MySQL Server, usando la consulta SQL "SHOW TABLES". Esta función usa la clase MySqlCommand para componer el comando SQL "SHOW TABLES" y la clase "MySqlDataReader" para guardar el resultado de la ejecución de la consulta SQL con "ExecuteReader". En el "MySqlDataReader" quedará almacenado el resultado de la consulta SQL. Para obtener el número de tablas usaremos la función anterior numeroRegistrosConsulta:
    Private Function numeroTablas() As Integer         Dim consultaSQL As MySqlCommand =             New MySqlCommand("show tables", conexion)         Dim dr As MySqlDataReader = consultaSQL.ExecuteReader()         numeroTablas = numeroRegistrosConsulta(dr)         dr.Close()     End Function
  • El botón "btConectar" tendrá el siguiente código en el evento "Click":
    Private Sub btConectar_Click(sender As System.Object,                  e As System.EventArgs) Handles btConectar.Click         conectarServidorMySQL()          Dim lista As List(Of String)         Dim i As Integer          lsBD.Items.Clear()          If lsBD.Text <> "" Then             bePanelNumTablas.Text =                 "| Nº tablas: " & CStr(numeroTablas())         End If          lista = esquemasMySQL()         For i = 0 To lista.Count - 1             lsBD.Items.Add(lista.Item(i).ToString)         Next      End Sub
  • El botón "btUsarEsquema" en su evento Click tendrá el siguiente código:
    Private Sub btUsarEsquema_Click(sender As System.Object,              e As System.EventArgs) Handles btUsarEsquema.Click         If lsBD.Text <> "" Then             Try                 If conexion.State = ConnectionState.Open Then                     conexion.Close()                 End If                  conexion.ConnectionString =                     "server=" & txtServidor.Text & ";" &                     "user id=" & txtUsuario.Text & ";" &                     "password=" & txtContrasena.Text & ";" &                     "port=" & txtPuerto.Text & ";" &                     "database=" & lsBD.Text & ";"                 conexion.Open()                 If lsBD.Text <> "" Then                     bePanelNumTablas.Text =                         "| Nº tablas: " & CStr(numeroTablas())                 End If                 bePanel2.Text = "Conectado | " &                     txtServidor.Text & "@" &                     lsBD.Text & "@" & txtUsuario.Text             Catch ex As Exception                 MsgBox("Error al conectar al servidor MySQL " &                        vbCrLf & vbCrLf & ex.Message)             End Try         Else             MsgBox("Debe seleccionar el esquema " &                    "(base de datos) a usar.",                 MsgBoxStyle.OkOnly + MsgBoxStyle.Information)             lsBD.Focus()         End If     End Sub
  • El botón "btEjecutar" tendrá el siguiente código en su evento "Click":
    Private Sub btEjecutar_Click(sender As System.Object,                 e As System.EventArgs) Handles btEjecutar.Click         Dim consultaSQL As MySqlCommand =             New MySqlCommand(txtSQL.Text, conexion)          'Consulta SQL que devuelve registros (SELECT)         If opDatos.Checked Then             Dim ds As DataSet = New DataSet()             Dim DataAdapter1 As MySqlDataAdapter =                 New MySqlDataAdapter()              Try                 DataAdapter1.SelectCommand = consultaSQL                 DataAdapter1.Fill(ds, "Tabla")                 DataGridView1.DataSource = ds                 DataGridView1.DataMember = "Tabla"                  bePanelNumRegistros.Text = "| Nº registros: " &                     CStr(ds.Tables(0).Rows.Count)             Catch ex As MySqlException                 MsgBox("Error al ejecutar consulta SQL: " &                        vbCrLf & vbCrLf & ex.ErrorCode & " " &                        ex.Message,                        MsgBoxStyle.OkOnly + MsgBoxStyle.Critical)             End Try         End If          'Consulta SQL que no devuelve registros          '(INSERT, DELETE, UPDATE, CREATE, DROP)         If opNoDatos.Checked Then             Dim numRegistrosAfectados As Integer             Dim comandoSQL As New MySqlCommand             Try                 comandoSQL.Connection = conexion                 comandoSQL.CommandText = txtSQL.Text                 numRegistrosAfectados = comandoSQL.ExecuteNonQuery()                 bePanelNumRegistros.Text = "| Nº registros afectados: " &                     CStr(numRegistrosAfectados)                 MsgBox("Consulta SQL ejecutada correctamente en " &                      "servidor MySQL. Número de registros afectados: " &                      CInt(numRegistrosAfectados),                      MsgBoxStyle.OkOnly + MsgBoxStyle.Information)             Catch ex As MySqlException                 MsgBox("Error al ejecutar consulta SQL: " &                        vbCrLf & vbCrLf & ex.ErrorCode & " " &                        ex.Message,                        MsgBoxStyle.OkOnly + MsgBoxStyle.Critical)             End Try         End If     End Sub
En este código mostramos cómo ejecutar una consulta que no devuelve datos (de tipo INSERT, CREATE, DROP, DELETE, UPDATE):
           Dim numRegistrosAfectados As Integer             Dim comandoSQL As New MySqlCommand             Try                 comandoSQL.Connection = conexion                 comandoSQL.CommandText = txtSQL.Text                 numRegistrosAfectados = comandoSQL.ExecuteNonQuery()                 bePanelNumRegistros.Text = "| Nº registros afectados: " &                     CStr(numRegistrosAfectados)
El código para ejecutar una consulta SQL que sí devuelve registros (SELECT) y que, además, enlazamos con un componente visual para mostrar el resultado al usuario en un DataGridView:
            Dim ds As DataSet = New DataSet()             Dim DataAdapter1 As MySqlDataAdapter =                 New MySqlDataAdapter()              Try                 DataAdapter1.SelectCommand = consultaSQL                 DataAdapter1.Fill(ds, "Tabla")                 DataGridView1.DataSource = ds                 DataGridView1.DataMember = "Tabla"

La aplicación AjpdSoft Acceso nativo MySQL VB.Net en funcionamiento

El funcionamiento de AjpdSoft Acceso nativo MySQL VB.Net es bastante sencillo, ejecutando la aplicación, introduciremos los siguientes datos:
  • Servidor: nombre de red (hostname) o dirección IP del servidor de MySQL Server.
  • Puerto: puerto de conexión con el servidor de MySQL Server, por defecto 3306.
  • Usuario: nombre de usuario de MySQL Server con permisos suficientes para las tareas que queramos realizar.
  • Contraseña: contraseña del usuario anterior.
Una vez introducidos los datos anteriores pulsaremos en el botón "Conectar con servidor" para establecer la conexión nativa con el servior de MySQL Server indicado. La aplicación obtendrá los esquemas (bases de datos) a los que tenga acceso el usuario especificado, para trabar un una base de datos la seleccionaremos en el desplegable de "Usar el esquema (BD)" y pulsaremos el botón "Usar el esquema".
Una vez conectados al servidor, introduciremos cualquier consulta SQL (INSERT, DELETE, UPDATE, CREATE, DROP, SELECT), marcaremos el check correspondiente, si la consulta devuelve registros (SELECT) se marcará "Devuelve datos" , en caso contrario se marcará "No devuelve datos". Pulsaremos el botón "Ejecutar" para enviar la consulta SQL al servidor de MySQL Server. Si la consulta devuelve registros los mostrará el el grid de abajo. Si no devuelve registros la aplicación mostrará un mensaje con el número de registros afectados por la consulta SQL:
Desarrollar aplicación VB.Net con acceso nativo a MySQL Server mediante Connector/Net

Qué se necesita en el equipo cliente para ejecutar una aplicación VB.Net con acceso nativo a MySQL Server

Para distribuir nuestra aplicación sin necesidad de instalador, en el equipo donde será ejecutada necesitaremos:
  • El ejecutable de la aplicación compilado en Visual Basic .Net.
  • El fichero mysql.data.dll descargado con el MySQL Connector/Net
  • La versión .Net Framework usada para el proyecto: podremos descargar Microsoft .Net Framework desde:
http://www.microsoft.com/downloads/es-es/details.aspx?FamilyID=9cfb2d51-5ff4-4491-b0e5-b386f32c0992
(la URL puede variar)
Con estos dos ficheros (ejecutable y dll) y el Microsoft .Net Framework descargado he instalado, podremos utilizar la aplicación, por ejemplo, en un equipo con Microsoft Windows XP, sin realizar ninguna instalación (salvo .Net Framework):
Qué se necesita en el equipo cliente para ejecutar una aplicación VB.Net con acceso nativo a MySQL Server

Código fuente completo aplicación AjpdSoft Acceso nativo MySQL VB.Net

A continuación mostramos el código fuente (source code) completo de la aplicación de ejemplo AjpdSoft Acceso nativo MySQL VB.Net:
Imports MySql.Data.MySqlClient   Public Class formAccesoNativoMySQL      Friend conexion As MySqlConnection      Private Function numeroRegistrosConsulta( _                 ByVal dr As MySqlDataReader) As Integer         Dim numeroRegistros As Integer = 0         Do While dr.Read             numeroRegistros = numeroRegistros + 1         Loop         numeroRegistrosConsulta = numeroRegistros     End Function      Private Function numeroTablas() As Integer         Dim consultaSQL As MySqlCommand =             New MySqlCommand("show tables", conexion)         Dim dr As MySqlDataReader = consultaSQL.ExecuteReader()         numeroTablas = numeroRegistrosConsulta(dr)         dr.Close()     End Function       Private Function esquemasMySQL() As List(Of String)         Dim listaEsquemas As List(Of String)          listaEsquemas = New List(Of String)          Dim consultaSQL As MySqlCommand =             New MySqlCommand("SHOW DATABASES", conexion)          Dim dr As MySqlDataReader = consultaSQL.ExecuteReader         Do While dr.Read             listaEsquemas.Add(dr.Item("Database"))         Loop         esquemasMySQL = listaEsquemas     End Function      Private Sub conectarServidorMySQL()         Try             conexion = New MySqlConnection()             conexion.ConnectionString =                 "server=" & txtServidor.Text & ";" &                 "user id=" & txtUsuario.Text & ";" &                 "password=" & txtContrasena.Text & ";" &                 "port=" & txtPuerto.Text & ";" &                 "database=" & lsBD.Text & ";"             conexion.Open()             If lsBD.Text <> "" Then                 bePanelNumTablas.Text = CStr(numeroTablas())             End If             bePanel2.Text = "Conectado a servidor " &                 txtServidor.Text         Catch ex As Exception             MsgBox("Error al conectar al servidor MySQL " &                    vbCrLf & vbCrLf & ex.Message,                    MsgBoxStyle.OkOnly + MsgBoxStyle.Critical)         End Try     End Sub      Private Sub btConectar_Click(sender As System.Object,                  e As System.EventArgs) Handles btConectar.Click         conectarServidorMySQL()          Dim lista As List(Of String)         Dim i As Integer          lsBD.Items.Clear()          If lsBD.Text <> "" Then             bePanelNumTablas.Text =                 "| Nº tablas: " & CStr(numeroTablas())         End If          lista = esquemasMySQL()         For i = 0 To lista.Count - 1             lsBD.Items.Add(lista.Item(i).ToString)         Next      End Sub      Private Sub btEjecutar_Click(sender As System.Object,                 e As System.EventArgs) Handles btEjecutar.Click         Dim consultaSQL As MySqlCommand =             New MySqlCommand(txtSQL.Text, conexion)          'Consulta SQL que devuelve registros (SELECT)         If opDatos.Checked Then             Dim ds As DataSet = New DataSet()             Dim DataAdapter1 As MySqlDataAdapter =                 New MySqlDataAdapter()              Try                 DataAdapter1.SelectCommand = consultaSQL                 DataAdapter1.Fill(ds, "Tabla")                 DataGridView1.DataSource = ds                 DataGridView1.DataMember = "Tabla"                  bePanelNumRegistros.Text = "| Nº registros: " &                     CStr(ds.Tables(0).Rows.Count)             Catch ex As MySqlException                 MsgBox("Error al ejecutar consulta SQL: " &                        vbCrLf & vbCrLf & ex.ErrorCode & " " &                        ex.Message,                        MsgBoxStyle.OkOnly + MsgBoxStyle.Critical)             End Try         End If          'Consulta SQL que no devuelve registros          '(INSERT, DELETE, UPDATE, CREATE, DROP)         If opNoDatos.Checked Then             Dim numRegistrosAfectados As Integer             Dim comandoSQL As New MySqlCommand             Try                 comandoSQL.Connection = conexion                 comandoSQL.CommandText = txtSQL.Text                 numRegistrosAfectados = comandoSQL.ExecuteNonQuery()                 bePanelNumRegistros.Text = "| Nº registros afectados: " &                     CStr(numRegistrosAfectados)                 MsgBox("Consulta SQL ejecutada correctamente en " &                      "servidor MySQL. Número de registros afectados: " &                      CInt(numRegistrosAfectados),                      MsgBoxStyle.OkOnly + MsgBoxStyle.Information)             Catch ex As MySqlException                 MsgBox("Error al ejecutar consulta SQL: " &                        vbCrLf & vbCrLf & ex.ErrorCode & " " &                        ex.Message,                        MsgBoxStyle.OkOnly + MsgBoxStyle.Critical)             End Try         End If     End Sub      Private Sub btUsarEsquema_Click(sender As System.Object,              e As System.EventArgs) Handles btUsarEsquema.Click         If lsBD.Text <> "" Then             Try                 If conexion.State = ConnectionState.Open Then                     conexion.Close()                 End If                  conexion.ConnectionString =                     "server=" & txtServidor.Text & ";" &                     "user id=" & txtUsuario.Text & ";" &                     "password=" & txtContrasena.Text & ";" &                     "port=" & txtPuerto.Text & ";" &                     "database=" & lsBD.Text & ";"                 conexion.Open()                 If lsBD.Text <> "" Then                     bePanelNumTablas.Text =                         "| Nº tablas: " & CStr(numeroTablas())                 End If                 bePanel2.Text = "Conectado | " &                     txtServidor.Text & "@" &                     lsBD.Text & "@" & txtUsuario.Text             Catch ex As Exception                 MsgBox("Error al conectar al servidor MySQL " &                        vbCrLf & vbCrLf & ex.Message)             End Try         Else             MsgBox("Debe seleccionar el esquema " &                    "(base de datos) a usar.",                 MsgBoxStyle.OkOnly + MsgBoxStyle.Information)             lsBD.Focus()         End If     End Sub End Class 

Artículos relacionados

Créditos

Artículo realizado íntegramente por Alonsojpd miembro fundador del Proyecto AjpdSoft.