Bases de datos

From Apache OpenOffice Wiki
< ES‎ | Manuales‎ | GuiaAOO‎ | TemasAvanzados‎ | Macros‎ | StarBasic‎ | TrabajandoConCalc
Revision as of 15:21, 28 March 2013 by Salva (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search


Editing.png Esta página está en estado borrador.

La manipulación y administración de datos, es una de las necesidades más recurrentes en usuarios de hoja de cálculo, esto no es gratuito, pues las herramientas presentes en ellas, facilitan enormemente esta tarea. Para el mejor aprovechamiento de este capitulo, sería deseable que conocieras los siguientes conceptos: base de datos, tabla, campo, registro, consulta, SQL, clave primaria, índice, relaciones e integridad referencial. Dada la amplia documentación existente en castellano de estos temas, no duplicaremos esfuerzos y queda de tu parte investigar acerca de ello si no lo dominas.


También, es indispensable que las bases de datos que usemos, al menos en este capitulo, estén registradas en OOo.


Registrar una base de datos

Para registrar una base de datos seguimos los siguientes pasos, ve al menú Herramientas > Opciones... > OpenOffice.org Base > Bases de datos, donde tienes que ver las siguientes opciones.


ES StarBasic BasesDeDatos.12.png


Da clic en el botón de comando Nuevo..., para ver el siguiente cuadro de dialogo.


ES StarBasic BasesDeDatos.11.png


En el cual, le darás clic al botón de comando Examinar..., que te mostrará el conocido cuadro de dialogo para seleccionar archivos, navega hasta la ruta donde hayas guardado la base de datos o este localizada la base de datos que quieras registrar y selecciónala, por último da un clic en el botón de comando Abrir.


ES StarBasic BasesDeDatos.10.png


Al dar clic en el botón de comando Abrir, tienes que regresar al cuadro de dialogo anterior, pero, ahora, tienes que ver la ruta completa del archivo que acabas de seleccionar, así como el nombre propuesto con el que se registrará la base de datos, este nombre puedes personalizarlo a tu gusto pues acepta espacios incluso, pero mi recomendación es que no uses ni espacios ni caracteres “extraños”, para nuestro ejemplo, dejaremos el propuesto.


ES StarBasic BasesDeDatos.09.png


Da un clic en el botón de comando Aceptar para regresar al primero cuadro de dialogo, donde, ahora, tendrás que ver la nueva base de datos registrada.


ES StarBasic BasesDeDatos.08.png


Agrega de una vez la otra base de datos que acompaña a estos apuntes, se llama “Videoteca” y también la usaremos para nuestros ejemplos. Solo te resta cerrar este cuadro de dialogo con el botón de comando Aceptar.


Importando datos

Importa datos desde bases de datos registradas en OpenOffice.org, es trivial, solo tienes que presionar la tecla  F4 , que te mostrará estas bases en la ventana Fuente de datos, junto con todos sus objetos; tablas y consultas, seleccionar la base de datos de nuestro interés, expandir para mostrar su contenido, seleccionar la tabla o consulta que quieras, el contenido de dicho objeto, te lo mostrará en el panel derecho del examinador de fuentes de datos, solo te resta seleccionar todo con el botón de seleccionar todo, arrastrar a tu documento y listo, tienes que tener los datos seleccionados, como en la siguiente imagen.


ES StarBasic BasesDeDatos.05.png


En este capitulo, aprenderemos a hacer esto mismo, pero claro, por código, con el cual, podrás comprobarlo más adelante, tenemos posibilidades “casi” ilimitadas para importar nuestros datos.


Para importar datos, de bases de datos previamente registradas en OpenOffice.org, usamos el método doImport, presente en rangos de datos, a este método, se le pasa una matriz de propiedades con las indicaciones de que y como queremos importar, por ejemplo.


 Sub BasesDeDatos1()
 Dim oHojaActiva As Object
 Dim sBaseDatos As String
 Dim sTabla As String
 Dim mOpcBD(2) As New "com.sun.star.beans.PropertyValue"
 
     'El nombre de nuestra base de datos
     sBaseDatos = "Directorio"
     'La tabla que nos interesa traer
     sTabla = "tblContactos"
     'La hoja activa
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
 
     'Las propiedades de la importación, primero el nombre de la base de datos
     mOpcBD(0).Name = "DatabaseName"
     mOpcBD(0).Value = sBaseDatos
     'El tipo de objeto fuente
     mOpcBD(1).Name = "SourceType"
     mOpcBD(1).Value = com.sun.star.sheet.DataImportMode.TABLE
     'El nombre del objeto fuente
     mOpcBD(2).Name = "SourceObject"
     mOpcBD(2).Value = sTabla
     'Importamos la tabla, a partir de la celda A1
     oHojaActiva.getCellRangeByName("A1").doImport( mOpcBD() ) 
 
 End Sub


Nota como estamos usando el nombre con que registramos la base de datos (DatabaseName), después, le estamos indicando el tipo de objeto (SourceType) que queremos importar, luego, el nombre del objeto (SourceObject) que queremos importar, por ultimo aplicamos la importación (doImport). El tipo de objeto esta determinado por la enumeración.


com.sun.star.sheet.DataImportMode Valor Valor en Interfaz
com.sun.star.sheet.DataImportMode.NONE 0 Ninguno
com.sun.star.sheet.DataImportMode.SQL 1 Instrucción SQL
com.sun.star.sheet.DataImportMode.TABLE 2 Tabla
com.sun.star.sheet.DataImportMode.QUERY 3 Consulta


Si estableces el tipo de objeto fuente en 0 (NONE), entonces tienes que pasarle una instrucción SQL, de lo contrario te dará error al importar. Todos los nombres de objetos (bases de datos, tablas, consultas, campos) distingue mayúsculas de minúsculas, por lo que tienes que ser muy cuidadoso de como nombrarlos y usar exactamente este nombre al importar, de lo contrario te puede alguno de los siguientes errores:


Cuando el nombre de la base de datos no corresponde.


ES StarBasic BasesDeDatos.07.png


Cuando la tabla este incorrecta.


ES StarBasic BasesDeDatos.06.png


En el siguiente ejemplo, importamos una tabla diferente en una celda diferente.


 Sub BasesDeDatos2()
 Dim oHojaActiva As Object
 Dim sBaseDatos As String
 Dim sTabla As String
 Dim mOpcBD(2) As New "com.sun.star.beans.PropertyValue"
 
     'El nombre de nuestra base de datos
     sBaseDatos = "Directorio"
     'La tabla que nos interesa traer
     sTabla = "tblPaises"
     'La hoja activa
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
 
     'Las propiedades de la importación, primero el nombre de la base de datos
     mOpcBD(0).Name = "DatabaseName"
     mOpcBD(0).Value = sBaseDatos
     'El tipo de objeto fuente
     mOpcBD(1).Name = "SourceType"
     mOpcBD(1).Value = com.sun.star.sheet.DataImportMode.TABLE
     'El nombre del objeto fuente
     mOpcBD(2).Name = "SourceObject"
     mOpcBD(2).Value = sTabla
     'Importamos la tabla, a partir de la celda A10
     oHojaActiva.getCellRangeByName("A10").doImport( mOpcBD() ) 
 
 End Sub


Ahora, importamos una consulta (QUERY) en vez de una tabla (TABLE).


 Sub BasesDeDatos3()
 Dim oHojaActiva As Object
 Dim sBaseDatos As String
 Dim sConsulta As String
 Dim mOpcBD(2) As New "com.sun.star.beans.PropertyValue"
 
     sBaseDatos = "Directorio"
     'Ahora una consulta
     sConsulta = "qryCiudades"
     'La hoja activa
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
 
     mOpcBD(0).Name = "DatabaseName"
     mOpcBD(0).Value = sBaseDatos
     'El tipo de objeto fuente, una consulta
     mOpcBD(1).Name = "SourceType"
     mOpcBD(1).Value = com.sun.star.sheet.DataImportMode.QUERY
     'El nombre del objeto fuente
     mOpcBD(2).Name = "SourceObject"
     mOpcBD(2).Value = sConsulta
     'Importamos la tabla, a partir de la celda A1
     oHojaActiva.getCellRangeByName("A1").doImport( mOpcBD() ) 
 
 End Sub


Tienes que tener la precaución de que el nombre del objeto corresponda a su tipo, si no, el método te devolverá un error:


ES StarBasic BasesDeDatos.04.png


Importamos una consulta diferente:


 Sub BasesDeDatos4()
 Dim oHojaActiva As Object
 Dim sBaseDatos As String
 Dim sConsulta As String
 Dim mOpcBD(2) As New "com.sun.star.beans.PropertyValue"
 
     sBaseDatos = "Directorio"
     'Una consulta
     sConsulta = "qryContactos"
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
 
     mOpcBD(0).Name = "DatabaseName"
     mOpcBD(0).Value = sBaseDatos
     mOpcBD(1).Name = "SourceType"
     mOpcBD(1).Value = com.sun.star.sheet.DataImportMode.QUERY
     mOpcBD(2).Name = "SourceObject"
     mOpcBD(2).Value = sConsulta
     oHojaActiva.getCellRangeByName("A1").doImport( mOpcBD() ) 
 
 End Sub


Cambiemos de tipo de objeto fuente, el siguiente ejemplo, hace exactamente lo mismo que el primer ejemplo, es decir, nos importa la tabla tblContactos.


 Sub BasesDeDatos5()
 Dim oHojaActiva As Object
 Dim sBaseDatos As String
 Dim sSQL As String
 Dim mOpcBD(2) As New "com.sun.star.beans.PropertyValue"
 
     sBaseDatos = "Directorio"
     'Establecemos la consulta SQL
     sSQL = "SELECT * FROM tblContactos"
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
 
     mOpcBD(0).Name = "DatabaseName"
     mOpcBD(0).Value = sBaseDatos
     mOpcBD(1).Name = "SourceType"
     'Observa como hemos cambiado el tipo de fuente a SQL
     mOpcBD(1).Value = com.sun.star.sheet.DataImportMode.SQL
     mOpcBD(2).Name = "SourceObject"
     mOpcBD(2).Value = sSQL
     oHojaActiva.getCellRangeByName("A1").doImport( mOpcBD() )
 
 End Sub


Entonces, ¿cual es la diferencia?, la primera, es obvio, es que estamos usando una instrucción SQL para importar los datos, pero... ¿que es SQL?, la respuesta sencilla; SQL es un lenguaje estructurado de consultas, nos permite recuperar “casi” cualquier dato de cualquier base de datos con soporte para SQL, la respuesta compleja nos podría llevar una libro completo. En los siguiente ejemplos, me limitaré a darte muestras de instrucciones SQL que sean lo suficientemente ilustrativas del poder y versatilidad de este lenguaje. SQL es un estándar, así que, en “teoría”, cualquier documentación de el “debería” servirte. Cuando importamos tablas o consultas, estas, se importan con todo su contenido, con SQL, podemos limitarnos exclusivamente a los datos que necesitamos, en el siguiente ejemplo, solo importamos tres (Nombre, Paterno y Materno) campos de la tabla (tblContactos).


 Sub BasesDeDatos6()
 Dim oHojaActiva As Object
 Dim sBaseDatos As String
 Dim sSQL As String
 Dim mOpcBD(2) As New "com.sun.star.beans.PropertyValue"
 
     sBaseDatos = "Directorio"
     'Establecemos la consulta SQL
     sSQL = "SELECT Nombre, Paterno, Materno FROM tblContactos"
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
 
     mOpcBD(0).Name = "DatabaseName"
     mOpcBD(0).Value = sBaseDatos
     mOpcBD(1).Name = "SourceType"
     mOpcBD(1).Value = com.sun.star.sheet.DataImportMode.SQL
     mOpcBD(2).Name = "SourceObject"
     mOpcBD(2).Value = sSQL
     oHojaActiva.getCellRangeByName("A1").doImport( mOpcBD() ) 
 
 End Sub


Observa como en el primer ejemplo de instrucción SQL, le indicamos que queremos todo (*) con el asterisco, en este segundo ejemplo, le indicamos explícitamente que campos queremos importar, de nuevo, ten mucho cuidado con los nombres de tus campos, si el campo no existe, el método te devolverá un error.


ES StarBasic BasesDeDatos.03.png


Nota como claramente nos esta diciendo que el campo no existe, recuerda que en los nombres se distingue entre mayúsculas y minúsculas.


Las instrucciones SQL, tiene unos modificadores que se llaman “clausulas”, estas no permiten complementar, limitar, filtrar y ordenar entre otras acciones a los datos importados. En el siguiente ejemplo, ordenamos (ORDER BY) los datos importados.


 Sub BasesDeDatos7()
 Dim oHojaActiva As Object
 Dim sBaseDatos As String
 Dim sSQL As String
 Dim mOpcBD(2) As New "com.sun.star.beans.PropertyValue"
 
     sBaseDatos = "Directorio"
     'Establecemos la consulta SQL
     sSQL = "SELECT Nombre, Paterno, Materno FROM tblContactos ORDER BY Paterno"
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
 
     mOpcBD(0).Name = "DatabaseName"
     mOpcBD(0).Value = sBaseDatos
     mOpcBD(1).Name = "SourceType"
     mOpcBD(1).Value = com.sun.star.sheet.DataImportMode.SQL
     mOpcBD(2).Name = "SourceObject"
     mOpcBD(2).Value = sSQL
     oHojaActiva.getCellRangeByName("A1").doImport( mOpcBD() ) 
 
 End Sub


El nombre de los campos, casi siempre se establece de forma que sea fácil de recordar y de manipular por el programador, pero muchas veces este nombre no le dice mucho al usuario, para estos casos, tenemos una clausula para cambiar el nombre original del campo, por uno de más fácil lectura para el usuario, veamos como.


 Sub BasesDeDatos8()
 Dim oHojaActiva As Object
 Dim sBaseDatos As String
 Dim sSQL As String
 Dim mOpcBD(2) As New "com.sun.star.beans.PropertyValue"
 
     sBaseDatos = "Directorio"
     'Establecemos la consulta SQL
     sSQL = "SELECT Nombre, Paterno As ""Apellido Paterno"", Materno As ""Apellido Materno"", Cumple As Cumpleaños FROM tblContactos ORDER BY Paterno"
 
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
 
     mOpcBD(0).Name = "DatabaseName"
     mOpcBD(0).Value = sBaseDatos
     mOpcBD(1).Name = "SourceType"
     mOpcBD(1).Value = com.sun.star.sheet.DataImportMode.SQL
     mOpcBD(2).Name = "SourceObject"
     mOpcBD(2).Value = sSQL
     oHojaActiva.getCellRangeByName("A1").doImport( mOpcBD() ) 
 
 End Sub


Nota el uso de las dobles comillas, esto es indispensable cuando el nombre usado (AS) contenga espacios como en nuestro ejemplo, y estas, deben ser exactamente las necesarias, ni una más ni una menos, ten cuidado con su uso. Si revisas la estructura de la tabla tblContactos notaras que el campo Cumple es de tipo fecha (Date), para hacer consultas sobre campos de fechas, tienes que usar una sintaxis muy singular, por ejemplo, para consultar una fecha especifica, usamos.


 sSQL = "SELECT * FROM tblContactos WHERE Cumple={ D '1974-01-15' }"


Observa como todo el criterio de la fecha va encerrado entre llaves, nota el uso de la letra D (de Date) y las comillas en la fecha, además, el orden tiene que ser precisamente así año-mes-día, si estableces correctamente este criterio, no tendrás problemas con el manejo de fechas.


Cambiemos de base de datos, en el siguiente ejemplo, usamos la base de datos “Videoteca”, y mostramos como podemos ordenar de forma ascendente (ASC) por un campo y de forma descendente (DESC) por otro.


 Sub BasesDeDatos9()
 Dim oHojaActiva As Object
 Dim sBaseDatos As String
 Dim sSQL As String
 Dim mOpcBD(2) As New "com.sun.star.beans.PropertyValue"
 
     sBaseDatos = "Videoteca"
     'Establecemos la consulta SQL
     sSQL = "SELECT * FROM tblVideo ORDER BY Genero ASC, Director DESC"
 
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
 
     mOpcBD(0).Name = "DatabaseName"
     mOpcBD(0).Value = sBaseDatos
     mOpcBD(1).Name = "SourceType"
     mOpcBD(1).Value = com.sun.star.sheet.DataImportMode.SQL
     mOpcBD(2).Name = "SourceObject"
     mOpcBD(2).Value = sSQL
     oHojaActiva.getCellRangeByName("A1").doImport( mOpcBD() ) 
 
 End Sub


Como en los ejemplos siguientes solo cambia la instrucción SQL, solo te mostraré esta, mientras no se indique lo contrario, seguiremos usando la base de datos “Videoteca”.


En el siguiente ejemplo, filtramos los datos importados por el campo Pais.


 sSQL = "SELECT * FROM tblVideo WHERE Pais='México'"


Siempre que quieras establecer un criterio de filtrado usa WHERE en donde estableces el deseado y nota también, como hacemos uso de comillas simples para el parámetro del criterio, esto, es importante.


La siguiente instrucción, nos importa todos los títulos que comiencen por la letra “V”, observa el uso de una nueva clausula LIKE sin signo igual y con el símbolo de porcentaje después de la letra deseada sin olvidar el uso de las comillas simples.


     sSQL = "SELECT * FROM tblVideo WHERE Titulo LIKE 'V%'"


Ahora, importamos todas las películas que “contengan” la palabra “anillos”.


     sSQL = "SELECT * FROM tblVideo WHERE Titulo LIKE '%anillos%'"


Con la siguiente instrucción, importamos todas las películas que duren entre 60 y 90 minutos ordenados por duración, tenemos una nueva clausula para importar datos entre dos valores (BETWEEN) junto con el operador “y” (AND).


     sSQL = "SELECT * FROM tblVideo WHERE Duracion BETWEEN 60 AND 90 ORDER BY Duracion"


Ahora, importamos las películas que sean de cualquiera (OR) de los siguientes años; 1974 o 1986 o 2000, observa que volvemos a hace uso de la forma .


     sSQL = "SELECT * FROM tblVideo WHERE Año=1974 OR Año=1986 OR Año=2000"


Nuestro siguiente ejemplo, hace exactamente lo mismo que el anterior, solo que ahora hacemos uso de la clausula IN para establecer los años deseados.


     sSQL = "SELECT * FROM tblVideo WHERE Año IN(1974,1986,2000)"


El siguiente ejemplo es muy interesante, nos permite obtener un listado con registros únicos (DISTINCT), lo que nos da la posibilidad de importar, por ejemplo, todos los directores que tenemos en nuestra videoteca, además, es una buena alternativa para encontrar campos mal capturados, por ejemplo, si algún campo tiene un solo espacio de más, con esta clausula te darás cuenta cuales de ellos pueden tener este caso, ya que los considerará como dos registros diferentes.


     sSQL = "SELECT DISTINCT Director FROM tblVideo"


El lenguaje SQL, también nos permite hacer algunas operaciones sobre los campos, por ejemplo, en vez de regresar los distintos países que tenemos, solo los contamos (COUNT), nota que primero obtenemos los países (DISTINCT Pais), y después los contamos (COUNT), además, le establecemos un nombre a este resultado (AS ""Total Países"").


     sSQL = "SELECT COUNT(DISTINCT Pais) AS ""Total Países"" FROM tblVideo"


Podemos obtener, el total de minutos de nuestra videoteca, sumando (SUM) los minutos de duración de todas las películas.


     sSQL = "SELECT SUM(Duracion) AS ""Total Minutos"" FROM tblVideo"


U obtener el promedio (AVG) de duración por película.


     sSQL = "SELECT AVG(Duracion) AS ""Promedio en Minutos"" FROM tblVideo"


O la duración máxima.


     sSQL = "SELECT MAX(Duracion) AS ""Duración Máxima"" FROM tblVideo"


O la mínima.


     sSQL = "SELECT MIN(Duracion) AS ""Duración Mínima"" FROM tblVideo"


En el siguiente ejemplo, usamos una nueva clausula que nos sirve para agrupar (GROUP BY) el resultado por algún campo, para obtener al suma de minutos por genero, usamos la siguiente instrucción SQL.


     sSQL = "SELECT Genero, SUM(Duracion) AS ""Duración por Genero"" FROM tblVideo GROUP BY Genero"


Observa como en los ejemplos para obtener la película de máxima (MAX) y mínima (MIN) duración, efectivamente obtenemos el valor, pero no sabes que título es este, para saberlo, vamos a realizar una subconsulta, que no es otra cosa que consultas anidadas, en donde, el resultado de la consulta interior, es el criterio de filtro para la exterior, con en el siguiente ejemplo, ahora si, obtenemos todos los datos de la película de máxima duración en nuestra videoteca.


     sSQL = "SELECT * FROM tblVideo WHERE Duracion=(SELECT MAX(Duracion) FROM tblVideo)"


No te confundas, primero, obtenemos la máxima duración (SELECT MAX(Duracion) FROM tblVideo), solo el valor, después, este valor, lo establecemos como criterio (WHERE) de la consulta exterior, donde si devolvemos todos los campos, es muy importante el uso de los paréntesis para la consulta interior.


Los ejemplos de instrucciones SQL vistas en todos los ejemplos anteriores, son solo una muestra ínfima de su poder y versatilidad, pero creo, suficientes para tengas mucho para practicar y probar. El método doImport, no es el único método para consultar datos en bases de datos pero si el más sencillo.


Insertando nuevos datos

Las instrucciones SQL no solo sirven para importar datos, también nos sirven para insertar nuevos datos en las tablas de nuestra base de datos. En el siguiente ejemplo, importamos los países dados de alta en nuestra tabla tblPaises de nuestra base de datos Directorio.


 Sub BasesDeDatos10()
 Dim oHojaActiva As Object
 Dim sBaseDatos As String
 Dim sTabla As String
 Dim mOpcBD(2) As New "com.sun.star.beans.PropertyValue"
 
     sBaseDatos = "Directorio"
     sTabla = "tblPaises"
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
 
     mOpcBD(0).Name = "DatabaseName"
     mOpcBD(0).Value = sBaseDatos
     mOpcBD(1).Name = "SourceType"
     mOpcBD(1).Value = com.sun.star.sheet.DataImportMode.TABLE
     mOpcBD(2).Name = "SourceObject"
     mOpcBD(2).Value = sTabla
 
     oHojaActiva.getCellRangeByName("A1").doImport( mOpcBD() ) 
 
 End Sub


La importación anterior, tiene que haberte devuelto algo muy similar a.


ES StarBasic BasesDeDatos.02.png


Pero el método para importar (doImport), hace exactamente solo eso, importar, por lo que para insertar nuevos datos usaremos una técnica diferente.


Si revisas la estructura de la tabla tblPaises, observaras que esta formada por tres campos; Id, Pais y LDPais, el primero es un campo tipo entero, es la clave primaria y su inserción es automática, el segundo es un campo tipo texto y es requerido, es decir, no puede faltar, y el tercero, es un entero que puede o no puede estar, esto, la estructura de la tabla, el nombre de los campos, el tipo de campo y si es requerido o no, son datos indispensables para insertar nuevos datos, ya que, de no cumplir con algún requerimiento especifico o no coincidir el tipo de dato que se desea insertar con el tipo del campo de la tabla, lo más probable es que la instrucción no tenga éxito y te devuelva un error. Antes de empezar con los ejemplos propios de inserción de datos, veamos la nueva forma de acceder a nuestra base de datos, el siguiente código, te mostrará todas las bases de datos “registradas” en OpenOffice.org.


 Sub BasesDeDatos11()
 Dim oDBC As Object
 Dim mNombresBD() As String
 Dim co1 As Integer
 
     'Creamos el servicio para acceder y manipular las bases de datos
     oDBC = createUnoService("com.sun.star.sdb.DatabaseContext")
     'Obtenemos los nombres de las bases de datos registradas
     mNombresBD = oDBC.getElementNames()
     'Mostramos el nombre de cada una
     For co1 = LBound( mNombresBD ) To UBound ( mNombresBD )
         MsgBox mNombresBD(co1)
     Next
 
 End Sub


Para acceder a la base de datos de nuestro interés, usamos.


 Sub BasesDeDatos12()
 Dim oDBC As Object
 Dim oBD As Object
 Dim sBaseDatos As String
 
     'El nombre de la base de datos
     sBaseDatos = "Directorio"
     'Creamos el servicio para acceder y manipular las bases de datos
     oDBC = createUnoService("com.sun.star.sdb.DatabaseContext")
     'Nos aseguramos de que exista la base de datos
     If oDBC.hasByName( sBaseDatos ) Then
         'Si existe, accedemos por el nombre
         oBD = oDBC.getByName( sBaseDatos )
         'Mostramos la ruta de la base de datos
         MsgBox ConvertFromURL( oBD.DatabaseDocument.URL )
     End If
 
 End Sub


El siguiente ejemplo, nos ilustra una nueva forma de hacer una consulta (executeQuery), diferente al método doImport, este nuevo método, tienen muchas variantes y posibilidades, pues nos da acceso al resultado de la consulta para manipular cada registro y cada campo según nuestras necesidades.


 Sub BasesDeDatos13()
 Dim oDBC As Object
 Dim oBD As Object
 Dim oConexion As Object
 Dim oDeclaracion As Object
 Dim oResultado As Object
 Dim sBaseDatos As String
 Dim sSQL As String
 
     'El nombre de la base de datos
     sBaseDatos = "Directorio"
     sSQL = "SELECT * FROM tblPaises"
     'Creamos el servicio para acceder y manipular las bases de datos
     oDBC = createUnoService("com.sun.star.sdb.DatabaseContext")    
     'Nos aseguramos de que exista la base de datos
     If oDBC.hasByName( sBaseDatos ) Then
         'Si existe, accedemos por el nombre
         oBD = oDBC.getByName( sBaseDatos )
         'Creamos una conexion a la base de datos
         oConexion = oBD.getConnection("","")
         'Creamos un objeto para las instrucciones SQL
         oDeclaracion = oConexion.createStatement()
         'Ejecutamos la consulta
         oResultado = oDeclaracion.executeQuery( sSQL)
         'Si hay resultados
         If Not IsNull( oResultado ) Then
             Do While oResultado.next
                 'Mostramos el contenido del campo
                 MsgBox oResultado.getString( 2 )
             Loop
         End If
     End If
 
 End Sub


Ahora si, veamos como insertar un nuevo registro en nuestra base de datos.


 Sub BasesDeDatos14()
 Dim oDBC As Object
 Dim oBD As Object
 Dim oConexion As Object
 Dim oDeclaracion As Object
 Dim sBaseDatos As String
 Dim sSQL As String
 
     'El nombre de la base de datos
     sBaseDatos = "Directorio"
     sSQL = "INSERT INTO ""tblPaises"" (""Pais"") VALUES ('Honduras')"
     'Creamos el servicio para acceder y manipular las bases de datos
     oDBC = createUnoService("com.sun.star.sdb.DatabaseContext")    
     'Nos aseguramos de que exista la base de datos
     If oDBC.hasByName( sBaseDatos ) Then
         'Si existe, accedemos por el nombre
         oBD = oDBC.getByName( sBaseDatos )
         'Creamos una conexion a la base de datos
         oConexion = oBD.getConnection("","")
         'Creamos un objeto para las instrucciones SQL
         oDeclaracion = oConexion.createStatement()
         'Ejecutamos la inserción de datos
         oDeclaracion.executeUpdate( sSQL)
     End If
 
 End Sub


Es importante que notes que estamos usando un nuevo método (executeUpdate) para ejecutar la instrucción SQL. Para insertar registros, usamos una nueva instrucción SQL (INSERT INTO), seguida de la tabla donde insertaremos los nuevos datos, entre paréntesis, los nombres de los campos, después la clausula para indicar los valores (VALUES) y por ultimo, los valores a insertar entre paréntesis. Nota que en la tabla y los campos, usamos doble comilla y en los valores a insertar, si estos son texto, usamos comillas simples. Recordemos que la tabla tblPaises esta conformada por tres campos, el primero se llama Id de tipo entero, que además es clave primaria y de inserción automática, por ello omitimos, tanto el campo como el valor, por que este, será automáticamente insertado, no obstante, es posible insertarlo si lo deseas, como en el siguiente ejemplo.


     sSQL = "INSERT INTO ""tblPaises"" (""Id"", ""Pais"") VALUES (11,'Honduras')"


Observa como indicamos el nombre del campo (Id) y su valor (11), pero, al ser este campo una clave primaria, estas “no admiten duplicados”, por lo que si el valor indicado ya existe, te dará un error como el siguiente, donde claramente nos indica que estamos violando la unicidad del índice, intentando insertar valores duplicados para la columna (campo) Id.


ES StarBasic BasesDeDatos.01.png


Aunque este error en tiempo de ejecución es interceptable y manipulable, como lo vimos en el capitulo Control de errores, si tienes un campo que es clave primaria y de inserción automática como el campo Id de nuestra tabla, la recomendación es que permitas al motor de bases de datos, se encargue de insertar el valor siguiente como en nuestro ejemplo, que tienes que ejecutar varias veces para que notes que efectivamente, inserta el valor automáticamente. Después tenemos el campo Pais, si ejecutaste la macro varias veces y haces la consulta de la tabla o la abres desde Base, notaras que ahora, tenemos varias veces el país recién insertado, ¿es esto correcto?, claro que no, la idea de una base de datos es tener la menor cantidad de información repetida, de hecho, “no debería” haber información repetida en una base de datos. Para evitar la duplicidad de datos en otro campo que no sea la clave primaria, tienes dos posibles soluciones; una, puedes crear un índice en este campo, en el cual se le indica que solo contenga datos únicos con lo cual, si se intentan agregar datos duplicados, obtendrás un error interceptable en tiempo de ejecución, para ello, tienes que modificar la tabla desde Base y agregar el índice manualmente (o por código) lo cual aprenderemos más adelante, por ahora, usaremos el segundo método, que consiste en consultar si el país ya existe o no, y actuar en consecuencia, una primera aproximación a esta solución seria.


 Sub BasesDeDatos15()
 Dim oDBC As Object
 Dim oBD As Object
 Dim oConexion As Object
 Dim oDeclaracion As Object
 Dim oResultado As Object
 Dim sBaseDatos As String
 Dim sSQL As String
 Dim sPais As String
 
     sPais = Trim( InputBox( "Introduce el nombre del nuevo país" ) )
     If sPais <> "" Then 
         sBaseDatos = "Directorio"
         sSQL = "SELECT Pais FROM ""tblPaises"" WHERE Pais='" & sPais & "'"
         oDBC = createUnoService("com.sun.star.sdb.DatabaseContext")    
         If oDBC.hasByName( sBaseDatos ) Then
             oBD = oDBC.getByName( sBaseDatos )
             oConexion = oBD.getConnection("","")
             oDeclaracion = oConexion.createStatement()
             'Verificamos que el país no exista
             oResultado = oDeclaracion.executeQuery( sSQL)
             oResultado.next()
             If oResultado.getRow = 0 Then
                 'Si no existe lo insertamos
                 sSQL = "INSERT INTO ""tblPaises"" (""Pais"") VALUES ('" & sPais & "')"
                 oDeclaracion.executeUpdate( sSQL)
                 MsgBox "El país: " & sPais & " se inserto correctamente en la base de datos"
             Else
                 oResultado.close()
                 MsgBox "El país: " & sPais & " ya existe en la base de datos"
             End If
             'Cerramos las conexiones        
             oDeclaracion.close()
             oConexion.close()
             'Liberamos la memoria
             oResultado = Nothing
             oDeclaracion = Nothing
             oConexion = Nothing
         End If
     Else
         MsgBox "El campo no puede estar vacío"
     End If
 
 End Sub


Aun con esta validación, es posible que haya todavía datos duplicados cuando intentemos introducir variantes como “México”, “MÉxico”, “MÉXico” o “MÉXICO”, esto es por que el campo distingue mayúsculas de minúsculas, de nuevo, tienes dos alternativas; la primero es obvia, haces la consulta y comparas (si hay resultado), el valor devuelto con el valor nuevo todo en mayúsculas o minúsculas según prefieras, la otra, es modificar la estructura de la tabla para que ignore esta distinción, salvo en contadas excepciones, esta segunda opción es más rápida, practica y segura y como siempre, tienes la ultima palabra. Modifica la macro anterior para que no distinga mayúsculas de minúsculas y permite al usuario seguir introduciendo países hasta que quiera presionando el botón Cancelar del cuadro de dialogo.


El ultimo campo de nuestra tabla es: LDPais, que es un entero, pero el campo no es requerido, por lo que puedes omitirlo como lo hemos hecho hasta ahora, o puedes insertarlo, como en el siguiente ejemplo:


     sSQL = "INSERT INTO ""tblPaises"" (""Pais"", ""LDPais"") VALUES ('Venezuela',45)"


Observa que al ser un número, no lleva comillas, no así el campo, “todos” llevan sus comillas dobles. En “teoría”, una base de datos ideal, no “debería” tener campos vacíos, por lo que, aunque no sea obligatorio, procura dejar vacíos la menor cantidad de campos posible, en algunas ocasiones, si un campo esta casi siempre vacío, tal vez podrías plantearte la posibilidad de eliminarlo de la tabla, aunque no es muy recomendable estar eliminando o insertando campos, es mucho mejor y más eficiente, “diseñar” tus tablas, anticipando lo mejor posible, su contenido y estructura y evitar en lo posible cambios constantes durante la implementación de tu código, te evitaras algunos dolores de cabeza.


Para terminar este tema, veamos un ejemplo donde se inserta una fecha, la cual, debe ir entre comillas simples y muy importante, en el orden año-mes-día, si no, te dará un error en tiempo de ejecución.


 Sub BasesDeDatos16()
 Dim oDBC As Object
 Dim oBD As Object
 Dim oConexion As Object
 Dim oDeclaracion As Object
 Dim sBaseDatos As String
 Dim sSQL As String
 
     sBaseDatos = "Directorio"
     sSQL = "INSERT INTO ""tblContactos"" (""Nombre"",""Paterno"",""Materno"",""Cumple"",""IdCiudad"") VALUES ('Juan','Gomez','Perez','1981-01-31',2)"
     oDBC = createUnoService("com.sun.star.sdb.DatabaseContext")    
     oBD = oDBC.getByName( sBaseDatos )
     oConexion = oBD.getConnection("","")
     oDeclaracion = oConexion.createStatement()
     oDeclaracion.executeUpdate( sSQL)
 
     oDeclaracion.close()
     oConexion.close()
     oDeclaracion = Nothing
     oConexion = Nothing
 
 End Sub


Las recomendaciones generales al insertar datos son: ten cuidado con el tipo de datos del campo destino, cuida de que no falte ningún campo requerido y cuida los campos que tienen alguna “relación” con un campo de otra tabla.


Actualizando datos

La actualización de datos en una tabla, es una acción recurrente en la manipulación de bases de datos. Veamos como hacerlo, el siguiente ejemplo, actualiza el campo LDPais de la tabla tblPaises pero solo el registro que cumple la condición.


 Sub BasesDeDatos17()
 Dim oDBC As Object
 Dim oBD As Object
 Dim oConexion As Object
 Dim oDeclaracion As Object
 Dim sBaseDatos As String
 Dim sSQL As String
 
     sBaseDatos = "Directorio"
     'Construimos la instrucción de actualización
     sSQL = "UPDATE ""tblPaises"" SET ""LDPais""=57 WHERE ""Pais""='Colombia'"
     oDBC = createUnoService("com.sun.star.sdb.DatabaseContext")    
     oBD = oDBC.getByName( sBaseDatos )
     oConexion = oBD.getConnection("","")
     oDeclaracion = oConexion.createStatement()
     oDeclaracion.executeUpdate( sSQL)
 
     oDeclaracion.close()
     oConexion.close()
     oDeclaracion = Nothing
     oConexion = Nothing
 
 End Sub


Para actualizar, usamos una nueva instrucción SQL (UPDATE), después establecemos (SET), el campo a actualizar y el nuevo valor, si hay más campo se separan por comas, por último, la condición (WHERE) para actualizar solo los registros deseados, cuidado, si no estableces un criterio, te actualizará “todos” los registros de tu tabla. Si el criterio no devuelve ningún resultado, no veras ningún mensaje, simplemente no hará ningún cambio en la tabla.


En el siguiente ejemplo, mostramos el país y la clave lada de cada uno con la posibilidad de cambiarlo.


 Sub BasesDeDatos18()
 Dim oDBC As Object
 Dim oBD As Object
 Dim oConexion As Object
 Dim oDeclaracion As Object
 Dim oDeclaracion1 As Object
 Dim oResultado AS Object
 Dim sBaseDatos As String
 Dim sSQL As String
 Dim sInfo As String
 Dim sClave As String
 
     sBaseDatos = "Directorio"
     sSQL = "SELECT Pais, LDPais FROM tblPaises"
     oDBC = createUnoService("com.sun.star.sdb.DatabaseContext")    
     oBD = oDBC.getByName( sBaseDatos )
     oConexion = oBD.getConnection("","")
     oDeclaracion = oConexion.createStatement()
     oDeclaracion1 = oConexion.createStatement()
     oResultado = oDeclaracion.executeQuery( sSQL)
 
     Do While oResultado.Next
         sInfo = "El pais: " & oResultado.getString(1) & " tiene como clave Lada: " & _
                 oResultado.getString(2) & Chr(13) & Chr(13) & "Introduce la nueva clave lada"
         sClave = Val(Trim(InputBox(sInfo)))
         If sClave > 0 Then
             sSQL = "UPDATE ""tblPaises"" SET ""LDPais""=" & sClave & " WHERE ""Pais""='" & oResultado.getString(1) & "'"
             oDeclaracion1.executeUpdate( sSQL)
         End If
     Loop        
 
     oResultado.close()
     oDeclaracion.close()
     oDeclaracion1.close()
     oConexion.close()
     oResultado = Nothing
     oDeclaracion = Nothing
     oDeclaracion1 = Nothing
     oConexion = Nothing
 
 End Sub


Observa que creamos dos declaraciones (createStatement), una es para la consulta de selección y la otra para la actualización, no puedes usar la misma, pues se ven afectadas una por la otra. En nuestro siguiente ejemplo, actualizamos la fecha del contacto con .


 Sub BasesDeDatos19()
 Dim oDBC As Object
 Dim oBD As Object
 Dim oConexion As Object
 Dim oDeclaracion As Object
 Dim sBaseDatos As String
 Dim sSQL As String
 
     sBaseDatos = "Directorio"
     'Construimos la instrucción de actualización
     sSQL = "UPDATE ""tblContactos"" SET ""Cumple""='1980-02-28' WHERE ""Id""=0"
     oDBC = createUnoService("com.sun.star.sdb.DatabaseContext")    
     oBD = oDBC.getByName( sBaseDatos )
     oConexion = oBD.getConnection("","")
     oDeclaracion = oConexion.createStatement()
     oDeclaracion.executeUpdate( sSQL)
 
     oDeclaracion.close()
     oConexion.close()
     oDeclaracion = Nothing
     oConexion = Nothing
 
 End Sub


Al igual que en la inserción, la fecha debe cumplir el orden año-mes-día y estar entre comillas simples. Cuida respetar el tipo de dato del campo a actualizar.


Borrando datos

Borrar datos es sumamente simple, por ello, ten mucho cuidado cuando uses esta instrucción, el siguiente ejemplo borra un país de la tabla.


 Sub BasesDeDatos20()
 Dim oDBC As Object
 Dim oBD As Object
 Dim oConexion As Object
 Dim oDeclaracion As Object
 Dim sBaseDatos As String
 Dim sSQL As String
 
     sBaseDatos = "Directorio"
     'Construimos la instrucción de borrado
     sSQL = "DELETE FROM ""tblPaises"" WHERE ""LDPais""=57"
     oDBC = createUnoService("com.sun.star.sdb.DatabaseContext")    
     oBD = oDBC.getByName( sBaseDatos )
     oConexion = oBD.getConnection("","")
     oDeclaracion = oConexion.createStatement()
     oDeclaracion.executeUpdate( sSQL)
 
     oDeclaracion.close()
     oConexion.close()
     oDeclaracion = Nothing
     oConexion = Nothing
 
 End Sub


¡Cuidado!, si no estableces la condición, “borraras toda el contenido de la tabla”, es recomendable, en cualquier operación de borrado, así sea un campo, una tabla, un archivo o lo que sea, preguntarle al usuario si esta seguro de realizar la acción e informarle que esta no se puede deshacer. Las instrucciones de borrado, pueden afectar a tablas que estén relacionadas, tanto la actualización como el borrado, están ligados con un concepto en bases de datos que se llama integridad referencial, tema que sale de los propósitos de este libro, pero que si quieres profundizar en ello, tienes que conocerlo, estudiarlo, comprenderlo y aplicarlo en tus bases de datos, por ahora, con que tengas el cuidado de no dejar “huérfanos” a tus datos es más que suficiente. En el siguiente ejemplo, borramos todos los contactos que se llamen 'Juan'.


 Sub BasesDeDatos21()
 Dim oDBC As Object
 Dim oBD As Object
 Dim oConexion As Object
 Dim oDeclaracion As Object
 Dim sBaseDatos As String
 Dim sSQL As String
 
     sBaseDatos = "Directorio"
     'Construimos la instrucción de borrado
     sSQL = "DELETE FROM ""tblContactos"" WHERE ""Nombre""='Juan'"
     oDBC = createUnoService("com.sun.star.sdb.DatabaseContext")    
     oBD = oDBC.getByName( sBaseDatos )
     oConexion = oBD.getConnection("","")
     oDeclaracion = oConexion.createStatement()
     oDeclaracion.executeUpdate( sSQL)
 
     oDeclaracion.close()
     oConexion.close()
     oDeclaracion = Nothing
     oConexion = Nothing
 
 End Sub


Para consultar, insertar, actualizar o borrar datos, puedes tomar los valores de las celdas de Calc, con las mismas técnicas vista a lo largo de estos apuntes, solo ten cuidado con el correcto uso de las comillas, lo mejor, es crearte una función que agregue las comillas necesarias, esto, te aseguro, te evitará muchos dolores de cabeza.

Los temas vistos en este capitulo, son solo una pequeña parte de ese enorme tema que son las bases de datos, no obstante, tienes ya, herramientas suficientes para obtener mucho provecho de tus datos y tus conocimientos.



ES.Plantillas.Logo foro es.png
Si tienes dudas acerca de lo aquí explicado, tienes algún problema con AOO,
o quieres ampliar la información, no dudes en dirigirte al

Foro Oficial en español de Apache OpenOffice para Macros y API UNO

Personal tools