Bases de Datos usando DAO

26
Bases de Datos usando DAO Contenido: (los más recientes abajo) 1. Copiar la estructura de una tabla con Access 2. Ordenes SQL para cambiar los datos de una tabla. 3. Caracteres no "standards" en los nombres de los campos 4. Procesar una consulta SQL (Execute) 5. Procesar una consulta SQL creando un Recordset 6. Evitar el error al asignar un Null 7. Comprobar si un registro se está editando 8. Asignar a un Recordset los registros deseados 9. Compactar una base de datos, usando código VB (27/Feb) 10. Crear una base de datos, usando código VB (18/Abr) 11. Como crear un Formulario de Datos con un Grupo de Registros Subyacente (18/Abr) 12. Cambiar los caracteres extraños por ? (para usar en las consultas a bases de datos con LIKE) (20/Abr) 13. Procesar el resultado de una consulta con varias tablas para evitar registros duplicados (13/Jul) 14. Programación sobre la seguridad de Access (31/Ago) 15. Un método rápido para efectuar búsquedas (8/Sep) 16. Enumerar las tablas de una base de datos (17/Sep) 17. Capturar errores de ODBC (9/Abr/98) 18. Acceso a bases de datos SQL Server... 19. Cargar Imágenes de una base de datos sin usar el DataControl 20. Acceder a bases de datos de Access 2000 con el VB5 (05/Oct/99) 21. Un consejo si instalas VB6 SP4 para acceder a bases de datos de Access 2000 (10/Nov/00) 22. Ejemplo "simple" de acceso a datos DAO con el data control (Curso Básico entrega 34) (09/Jul/03) 23. Buscar en una base de datos DAO con el data control (Curso Básico entrega 35) (09/Jul/03) 24. Acceder a una base de datos DAO sin el data control (Curso Básico entrega 40) (09/Jul/03) 25. Realizar consultas en una base de datos DAO (Curso Básico entrega 40) (09/Jul/03) 26. Cómo manejar fechas en consultas, además de otros ejemplos, tanto para ADO como para DAO (09/Jul/03)

Transcript of Bases de Datos usando DAO

Page 1: Bases de Datos usando DAO

Bases de Datos usando DAOContenido: (los más recientes abajo)

1. Copiar la estructura de una tabla con Access 2. Ordenes SQL para cambiar los datos de una tabla. 3. Caracteres no "standards" en los nombres de los campos 4. Procesar una consulta SQL (Execute) 5. Procesar una consulta SQL creando un Recordset 6. Evitar el error al asignar un Null 7. Comprobar si un registro se está editando 8. Asignar a un Recordset los registros deseados 9. Compactar una base de datos, usando código VB (27/Feb)10. Crear una base de datos, usando código VB (18/Abr)11. Como crear un Formulario de Datos con un Grupo de Registros Subyacente

(18/Abr)12. Cambiar los caracteres extraños por ? (para usar en las consultas a bases de

datos con LIKE) (20/Abr)13. Procesar el resultado de una consulta con varias tablas para evitar registros

duplicados (13/Jul)14. Programación sobre la seguridad de Access (31/Ago)15. Un método rápido para efectuar búsquedas (8/Sep)16. Enumerar las tablas de una base de datos (17/Sep)17. Capturar errores de ODBC (9/Abr/98)18. Acceso a bases de datos SQL Server... 19. Cargar Imágenes de una base de datos sin usar el DataControl 20. Acceder a bases de datos de Access 2000 con el VB5 (05/Oct/99)21. Un consejo si instalas VB6 SP4 para acceder a bases de datos de Access 2000

(10/Nov/00)22. Ejemplo "simple" de acceso a datos DAO con el data control (Curso Básico

entrega 34) (09/Jul/03)23. Buscar en una base de datos DAO con el data control (Curso Básico entrega 35)

(09/Jul/03)24. Acceder a una base de datos DAO sin el data control (Curso Básico entrega 40)

(09/Jul/03)25. Realizar consultas en una base de datos DAO (Curso Básico entrega 40)

(09/Jul/03)26. Cómo manejar fechas en consultas, además de otros ejemplos, tanto para ADO

como para DAO (09/Jul/03)27. Instrucciones SQL para seleccionar, actualizar, eliminar datos, etc. (02/May/04)28. Conectar a una base de datos de SQL Server con VB6 (Abrir una tabla y mostrar

los campos/columnas) (10/Sep/04)29. Indicar el path de una base de datos usando el control data (18/Sep/04)

Ejemplo paso a paso de cómo usar un control data y DataGrid

Page 2: Bases de Datos usando DAO

 

 

1.- Copiar la estructura de una tabla con Access

Para copiar/duplicar la estructura de una tabla en una base de datos Access, sigue estos pasos:

1. Carga la base de datos en Access2. Selecciona la tabla a copiar3. En el menú de Edición, selecciona Copiar4. En el menú de Edición, selecciona Pegar5. Escribe el nuevo nombre de la tabla6. Selecciona "Estructura solamente"

Ya está la tabla "duplicada" en la misma base de datos, por si haces cambios de los que después te arrepientas.Si la intención es copiarla en otra base de datos, antes de seguir con el paso 4, cargar o crear la nueva base de datos y ya está. En el paso 6 puedes seleccionar "Estructura y Datos" si quieres copiar también los datos.

 

 

2.- Ordenes SQL para cambiar los datos de una tabla.

UPDATE tablaSET nombre_campo = 'nuevo_valor'WHERE opciones_a_tener_en_cuenta

Ejemplo: Actualizar la tabla Clientes poniendo el campo Agente a LIBRE si la fecha de ÚltimaVisita es anterior al 1 de Enero de 1996 (este es un caso sobre una base de datos que uso en mi trabajo, pero como ejemplo puede valer):

UPDATE Clientes SET Agente = 'LIBRE' WHERE [ÚltimaVisita] < DateValue('01/01/96')

Normalmente el campo de fechas será según tengáis configurado el sistema.

 

 

3.- Caracteres no "standard" en los nombres de los campos

Page 3: Bases de Datos usando DAO

Si al crear las tablas de la base de datos usas caracteres acentuados, eñes, espacios, etc. Cuando hagas una consulta o lo uses en un Recordset, etc, ponlos entre corchetes, fijates en cómo se usa ÚltimaVisita en el ejemplo anterior.

 

 

4.- Procesar una consulta SQL (Execute)

Para ejecutar una orden SQL en una base de datos, usar la orden Execute en la variable de una base de datos (Database)

'SQLTmp= orden SQL'Db será una base de datos:'Dim Db As Database 'Variable para las Bases de Datos'Set Db = OpenDatabase("Nombre_Base_Datos")

On Error Resume NextDb.Execute SQLTmp, dbFailOnErrorIf Err Then

MsgBox "Se ha producido un error al ejecutar la orden:" & vbCrLf & SQLTmpEnd If

 

 

5.- Procesar una consulta SQL creando un Recordset

Se creará un Recordset con el resultado de una consulta SQL realizada a uan base de datos, posteriormente se procesarán los datos que ha producido dicha consulta.Por ejemplo si tenemos una base de datos con nuestra colección discográfica, podríamos hacer una consulta con todos los CD's de Phil CollinsSuponiendo que el formato de los discos (CD, LP, etc.) es Formato y el Nombre del Autor está en Cantante, la orden a ejecutar sería:SQLTmp = "SELECT * FROM mis_discos WHERE Formato Like '*CD*' AND Cantante Like '*Phil Collins*'"Por supuesto se puede usar = en lugar de Like, si estamos seguros de que no necesitamos los comodines, ya que la consulta es "bastante" más rápida. Es decir quedaría así:SQLTmp = "SELECT * FROM mis_discos WHERE Formato = 'CD' AND Cantante = 'Phil Collins'"

'Ejecutar orden SQL con los datos solicitados

'Db será una base de datos:'Dim Db As Database 'Variable para las Bases de Datos

Page 4: Bases de Datos usando DAO

'Set Db = OpenDatabase("Nombre_Base_Datos")

Dim SQLTmp As StringDim MySnap As Recordset

SQLTmp = "select * from " & Nombre_Tabla & " <Consulta> " & " order by " & ClasificarSet MySnap = Db.OpenRecordset(SQLTmp, dbOpenSnapshot)Err = 0MySnap.MoveFirstIf Err Then

Err = 0'no hay datos, avisarMsgBox "No hay datos que coincidan con la búsqueda especificada,"

& vbCrLf & "(o no está bien realizada)", 64, "Listados"Exit Sub

End If

'Añadir el resultado a un ListList1.Clear

MySnap.MoveFirstDo Until MySnap.EOF

'Procesar los datos...'List1.AddItem MySnap("Cantante") & " " & MySnap("[Canción]") '...y

demás datos

MySnap.MoveNextLoopMySnap.Close

 

 

6.- Evitar el error al asignar un campo Null de una base de datos.

Además de evitar el error, es más rápido que usar If...Then... para comprobar si el campo es nulo o está vacío.

Para cadenas:

Cadena = "" & rs!Campo

Para números:

'Numero = 0 & rs!CampoNumero = CInt("0" & rs!Campo)

 

Page 5: Bases de Datos usando DAO

 

7.- Comprobar si un registro se está editando.

Esto puede ser útil si el programa tiene que acceder a una base de datos en red o bien si accedes en el mismo equipo a una base de datos.Lo que hay que hacer es usar EditMode y comprobar si se está editando.Veamos un ejemplo:

With Data1.Recordset 'Escribe el código para buscar el registro a editar, etc. '... Do While .EditMode = dbEditInProgress

DoEvents Loop 'Cuando llegue aquí, es que ya está libre... .Edit '...hacer los cambios al registro... .UpdateEnd With

Los valores que devuelve EditMode, pueden ser:

dbEditNone Si no se está editando.dbEditInProgress Se está editando actualmente.dbEditAdd Se ha añadido un registro con AddNew y el registro actual todavía está en el buffer.

 

 

8.- Seleccionar los registros que queremos en un Recordset

Para asignar a un Data (Recordset) los datos que quieras de una tabla, usa la propiedad Recordsource.

Data1.RecordSource = "SELECT * FROM Tabla WHERE (condiciones de selección) ORDER BY campo, [campo2]"Data1.Refresh

El Refresh que no se te olvide, si no quieres que produzca error.Condiciones de selección, serán las comparaciones (consulta) que quieres incluir para la selección.Por ejemplo, si quieres incluir todos los clientes de Málaga que tengan coche, clasificados por la población:

Data1.RecordSource = "SELECT * FROM Clientes WHERE Provincia = 'Málaga' AND Coche = 'Si' ORDER BY [Población]"

Page 6: Bases de Datos usando DAO

Fijate que Población está entre corchetes, esto es necesario, porque la ó (o acentuada) es un caracter "extraño" y se debe poner entre corchetes para que el Jet lo entienda. Lo mismo hay que hacer si el nombre del campo incluye espacios.Otra cosa a tener en cuenta es que si usas =, el contenido del campo "debe coincidir exactamente", si en Provincia tienes algo como: Málaga (Andalucía), no lo "encontrará". Para que lo incluya también, cambia el signo igual por LIKE:

Data1.RecordSource = "SELECT * FROM Clientes WHERE Provincia LIKE '*Málaga*' AND Coche = 'Si' ORDER BY [Población]"

Más cosas, en la parte ORDER BY, se pueden incluir más de un campo, separados por comas.El asterisco (*) que hay después de SELECT, es para que incluya todos los campos de la tabla.Si sólo quieres incluir algunos campos, especificalos en lugar del asterisco y separalos con comas:

Data1.RecordSource = "SELECT Nombre,Apellidos, [Población], Provincia, Coche FROM Clientes WHERE Provincia LIKE 'Málaga' AND Coche = 'Si' ORDER BY [Población]"

 

 

9.- Compactar una base de datos, usando código VB (27/Feb)

Este es el código que uso para compactar las bases de datos. Cosa que suelo hacer bastante a menudo, sobre todo en las que uso en la empresa, que cambian a diario.Por aquello de la seguridad, mantengo dos copias: la anterior y la última. Más vale prevenir. Nunca se sabe cuando se cortará la luz o se quedará colgado el equipo... así que, me curo en salud.

'Cerrar la base (esto sólo si la tienes abierta...)Db.Close'Liberar memoria y "desligarla"Set Db = Nothing''Tomar el nombre sin la extensiónsTmp = ""i = InStr(NombreBase, ".")If i Then p = i - 1Else p = Len(NombreBase)End IfsTmp = Left$(NombreBase, p)'Buscar \, para tomar el directorio (path)For i = p To 1 Step -1 If Mid$(NombreBase, i, 1) = "\" Then sTmp = Left$(NombreBase, i) Exit For End If

Page 7: Bases de Datos usando DAO

NextIf Right$(sTmp, 1) <> "\" Then sTmp = sTmp & "\"End If

'Todo este proceso es para estar seguro de que se quede una copia'en caso de que falle la compactación...dBaseTmp = sTmp & "~dBase2.mdb"If Len(Dir$(dBaseTmp)) Then Kill dBaseTmpIf Len(Dir$(sTmp & "~dBase1.mdb")) Then Kill sTmp & "~dBase1.mdb"

'Esta es la madre del cordero, se pueden usar otras "versiones", es cuestión de adecuarte.CompactDatabase NombreBase, dBaseTmp, dbLangSpanish, dbVersion20

'Guardar una copia de como estaba antesName NombreBase As sTmp & "~dBase1.mdb"'Esta es la base ya compactada, así que asignar el nombreName dBaseTmp As NombreBase'Borrar los ficheros LDBIf Len(Dir$(sTmp & "*.ldb")) Then Kill sTmp & "*.ldb"

 

 

10.- Crear una base de datos, usando código VB (18/Abr)

Aprovechando que he puesto la colaboración de Harvey Triana en esta página, pues te voy a poner cómo crear una base desde dentro del propio Visual Basic.Te recomiendo que veas el Proyecto Paso a Paso, en el que puedes tener el código completo y otras cosillas que aquí no se van a explicar.Este es el listado del procedimiento que se encargará de crear la base de datos. Por supuesto, deberás cambiar los nombres de los campos y tipos de datos a tu conveniencia, pero de esta forma, tienes algo por dónde empezar.

Private Sub CrearBase(sBase As String) 'Crear la base de datos indicada ' Dim Db As Database Dim Fd As Field Dim Tb As New TableDef 'Definir una Tabla Dim Idx As New Index 'Para crear un índice Dim i As Integer

'Crear base de datos, idioma español y para la versión 2.0 del Jet de Access '================================================================================ 'Si vas a adaptar este programa para VB3, usa dbVersion11 en lugar de dbVersion20

Page 8: Bases de Datos usando DAO

'================================================================================ Set Db = CreateDatabase(sBase, dbLangSpanish, dbVersion20) ' 'La constante dbVersion20 no aparece en la ayuda, en su lugar lo hace la dbVersion25 'pero ésa no está creada!!! ' 'Primero la tabla de las tareas Set Tb = Db.CreateTableDef("Tareas") 'Vamos a crear cada uno de los campos Set Fd = Tb.CreateField("ID", dbLong) 'Ahora vamos a asignar las propiedades de contador, etc. Fd.Attributes = dbAutoIncrField Or dbUpdatableField Or dbFixedField Tb.Fields.Append Fd 'El resto de los campos Set Fd = Tb.CreateField("Fecha", dbDate) Tb.Fields.Append Fd Set Fd = Tb.CreateField("Asunto", dbText, 255) Tb.Fields.Append Fd Set Fd = Tb.CreateField("Descripcion", dbMemo) Tb.Fields.Append Fd Set Fd = Tb.CreateField("FechaInicio", dbDate) Tb.Fields.Append Fd Set Fd = Tb.CreateField("FechaTermino", dbDate) Tb.Fields.Append Fd Set Fd = Tb.CreateField("Terminada", dbInteger) Tb.Fields.Append Fd 'Creamos un índice con el ID Idx.Name = "PrimaryKey" Idx.Unique = True Idx.Primary = True Idx.Fields = "ID" Tb.Indexes.Append Idx 'Añadimos la tabla a la base Db.TableDefs.Append Tb ' 'Creamos la otra tabla: Anotaciones Set Tb = Db.CreateTableDef("Anotaciones") 'El campo ID, es el contador, etc. Set Fd = Tb.CreateField("ID", dbLong) Fd.Attributes = dbAutoIncrField Or dbUpdatableField Or dbFixedField Tb.Fields.Append Fd 'El resto de los campos Set Fd = Tb.CreateField("Fecha", dbDate) Tb.Fields.Append Fd Set Fd = Tb.CreateField("Tema", dbText, 50) Tb.Fields.Append Fd Set Fd = Tb.CreateField("Asunto", dbText, 255) Tb.Fields.Append Fd Set Fd = Tb.CreateField("Medio", dbText, 255) Tb.Fields.Append Fd Set Fd = Tb.CreateField("Localizacion", dbText, 255) Tb.Fields.Append Fd Set Fd = Tb.CreateField("Descripcion", dbMemo) Tb.Fields.Append Fd

Page 9: Bases de Datos usando DAO

Set Fd = Tb.CreateField("Detalle", dbLongBinary) Tb.Fields.Append Fd 'Creamos un índice con el ID Set Idx = Nothing 'Quitar la referencia anterior Idx.Name = "PrimaryKey" Idx.Unique = True Idx.Primary = True Idx.Fields = "ID" Tb.Indexes.Append Idx 'Añadimos la segunda tabla a la base Db.TableDefs.Append Tb 'Cerramos la base Db.Close

MsgBox "Nueva base de datos " & sBase & " creada.", vbInformationEnd Sub

 

15.- Un método rápido para efectuar una búsqueda (8/Sep)

En este ejemplo, uso un recordset para hacer la búsqueda, el único requisito es que tenga un campo llamado ID, que será el que se devuelva con el dato encontrado.La rutina acepta búsquedas hacia delante y hacia atrás, para buscar hacia atrás la variable buscAtras será True.Se supone que además tienes una variable (Db) con la base de datos que estás usando.Aquí tienes el código...

Private Function BuscarEnBase(Optional ByVal sBusqueda As String = "") As Long 'Devuelve el número de ID ( 5/Jul/97) Dim sSQL As String Dim lID As Long

On Local Error Resume Next

If Len(sBusqueda) Then sSQL = "SELECT * FROM " & sTabla & " WHERE " & sBusqueda Set RsBuscar = Db.OpenRecordset(sSQL, dbOpenSnapshot) If Not RsBuscar.EOF Then 'Primera búsqueda If buscAtras Then RsBuscar.MoveLast End If lID = CLng(RsBuscar("ID")) Else lID = 0& End If Else If buscAtras Then RsBuscar.MovePrevious Else RsBuscar.MoveNext

Page 10: Bases de Datos usando DAO

End If lID = CLng(RsBuscar("ID")) End If If (lID = 0&) Or (Err <> 0) Then lID = 0& 'para que al seguir buscando se empiece por el primero If buscAtras Then RsBuscar.MoveLast RsBuscar.MoveNext Else RsBuscar.MoveFirst RsBuscar.MovePrevious End If End If Err = 0 BuscarEnBase = lIDEnd Function

Esto es un ejemplo de cómo se llamaría a esta función, usando el diálogo de buscar y reemplazar:

iFFAtras = True

If gsBuscar(sBuscar, cFFAc_Buscar + cFFAc_Atras, "Buscar datos") > cFFAc_IDLE Then sBuscar = Trim$(sBuscar) If Len(sBuscar) Then buscAtras = iFFAtras 'buscCompleta = iFFCompleta YaEstoyAqui = True LblStatus(1) = "Buscando " & sBuscar & "..." DoEvents 'Usar una rutina del tipo consulta (SQL) qID = BuscarEnBase(Text1(ControlActual).DataField & " LIKE '" & sBuscar & "*'") If qID Then Data1.Recordset.FindFirst "ID = " & CStr(qID) If Data1.Recordset.NoMatch Then qID = 0& End If End If If qID = 0& Then Beep MsgBox "No se ha hallado el dato buscado en el campo: " _

& Text1(ControlActual).DataField, vbOK + vbInformation, "Buscar"

 

16.- Enumerar las tablas de una base de datos (17/Sep)

Aquí te muestro como saber las tablas que existen en una base de datos. De esta forma puedes buscar si la que necesitas está en la base especificada o bien puedes

Page 11: Bases de Datos usando DAO

usarla para abrir "cualquier" tabla de una BD.Las rutinas sirven igual para VB3 (ejemplo aparte) y VB4 o superior.

Para probar esta rutina, en un form, añade un ListBox (List1) y un botón que al pulsarlo llame a EnumerarTablas, deberás cambiar la localización de la base de datos por la que sea en tu equipo...

'Ejemplo para VB4 o superiorPrivate Sub EnumerarTablas() Dim Db As Database Dim Td As TableDef

List1.Clear Set Db = OpenDatabase("D:\VB\Biblio.MDB") For Each Td In Db.TableDefs 'Sólo las tablas con atributo igual a CERO, 'son tablas normales If Td.Attributes = 0 Then List1.AddItem Td.Name End If Next Db.Close Set Db = NothingEnd Sub

'Para VB3: (en VB4 también se puede usar de esta forma)Private Sub EnumerarTablas() Dim INListTabl As Snapshot Dim Db As Database

List1.Clear Set Db = OpenDatabase("D:\VB\Biblio.MDB") Set INListTabl = Db.ListTables() INListTabl.MoveFirst Do Until INListTabl.EOF If INListTabl("Attributes") = 0 Then List1.AddItem INListTabl("Name") End If Loop Db.Close Set Db = NothingEnd Sub

Si lo que quieres es sólo comprobar si existe, en lugar de añadirla a un list, haces una comparación:

If Td.Name = miTabla Then ExisteTabla = TrueEnd If

17.- Un consejo si instalas VB6 SP4 para acceder a bases de datos de Access 2000 (10/Nov/00)

Page 12: Bases de Datos usando DAO

Si has leido el artículo sobre el acceso a bases de datos de Access 2000 usando el DAO Datacontrol (Acceder a bases de datos de Access 2000 con el VB5), verías que había un comentario sobre que no se puede usar ese control para acceder al nuevo formato de las bases de datos de Access 2000...Eso es cierto para el VB5 y para el VB6 pre-SP4, ya que el DAO Datacontrol que se incluye con la nueva "revisión" del VB6 SI reconoce dicho formato, además de que carga de forma automática la Microsoft DAO 3.6 Object Library, sin la cual no se puede acceder a las bases del Access 2000.Pero puedes llevarte una sorpresa si, (a pesar de indicar en las referencias que se use el nuevo motor de bases de datos 3.6), el VB te avisa de que no hay datos que mostrar...Esto es cierto si lo que estás probando es un proyecto que ya tuvieras hecho anteriormente, ya que con los nuevos proyectos no hay problemas... la razón es que, (si miras con un editor de textos el contenido de un formulario de VB), lo que se asigna a la propiedad Connect, para un control existente, es diferente del que se asigna para uno nuevo... con lo cual, si quieres que tus proyectos pre-SP4 funcionen sin problemas y sin tener que quitar el control existente y añadirlo de nuevo, (que sería la forma lógica de hacerlo), simplemente tendrás que cambiar la asignación que se le hace a dicha propiedad:

Nuevo: (vb6, SP4)------ Begin VB.Data Data1 Caption = "Data1" Connect = "Access 2000;"

Antiguo: (vb6 SP3... o anterior)-------- Begin VB.Data Data1 Caption = "Data1" Connect = "Access"

Es decir, cambia el "Access" por "Access 2000;"

Espero que este "truquillo" te alivie algún que otro quebradero de cabeza...

Nos vemosGuillermo

Page 13: Bases de Datos usando DAO

Curso Básico de Programaciónen Visual Basic

 

Entrega Cuarenta: 04/Sep/2001por Guillermo "guille" Som

Si quieres linkar con las otras entregas, desde el índice lo puedes hacer

 

Confío en que no acabes tarumba con tantas vueltas que estoy dando... la entrega anterior fue sobre las clases en Visual Basic y esta que te ofrezco ahora sigue los pasos de la entrega 36 sobre el acceso a bases de datos, aunque en esta ocasión sin usar el data control y con DAO. En otra entrega, veremos lo mismo, pero usando ADO... hasta que finalmente nos quedemos con ese tipo de acceso a datos, ya que Microsoft no "quiere" que sigamos usando DAO y lo trata como obsoleto, aunque no lo es tanto... pero como hay que está a la última en esto de programación, habrá que hacerles caso... así que también ve preparando el cuerpo, ya que a partir del 2002 la "nueva ola" será .NET y habrá que ir "concienciándose" de la nueva tecnología... pero no te preocupes que también podrás aprenderla... para que no te quedes atrás, aunque eso será en un futuro... talvez no muy lejano...

Cómo acceder a bases de datos DAO, sin el datacontrol.

Empecemos desde el principio... para que te vayas acostumbrando... aunque ya deberías saber crear tus propios formularios y añadir los controles que te indique... aunque prácticamente no te lo haya explicado en el curso, es algo que te enseñan en prácticamente cualquier libro e incluso en los "tutoriales" que incluye el Visual Basic.Sólo decirte que usando la versión 5CCE de Visual Basic no se pueden acceder a datos, así que tendrás que usar la versión Profesional o la Empresarial... pero si de verdad te quieres dedicar a esto de la programación... esa serán las versiones de las que deberías disponer... y no me preguntes dónde conseguirlas... ya que las venden en cualquier "tienda" de informática o en los distribuidores que puedes encontrar en Internet.

Vayamos al tema que nos interesa, ya que no es plan de hacer "marketing" gratuito a los distribuidores que "no sponsorizan" este curso básico... ¡hum!

Crea un nuevo proyecto, se creará un proyecto con un formulario.Añade los siguientes controles para que el formulario quede con el aspecto que te muestro a continuación, (que es parecido al usado en las entregas anteriores de acceso a datos): 

Page 14: Bases de Datos usando DAO

Aspecto del formulario en tiempo de diseño

Los controles usados son:En la parte superior:cmdMover, un array de 0 a 3Label1, un array de 0 a 2, Text1, un array de 0 a 2cmdAdd, cmdActualizar, cmdBorrarEl segundo grupo:Label2, Text2, Option1, Option2, cmdBuscar, cmdBuscarSigElbotón de salir es: cmdSalir

En el menú Proyecto/Referencias... selecciona Microsoft DAO 3.51 Object Library -aunque también puedes seleccionar cualquier otra que empiece por Microsoft DAO... cualquiera de ellas vale... puede que también tengas la 3.6 e incluso la 2.5/3.51 Compatibility Library, todo dependerá de la versión de DAO que tengas instalada-A diferencia de cuando seleccionas un componente, después de cerrar el cuadro de diálogo no verás nada nuevo en la ventana de herramientas, ya que las referencias no añaden nuevos controles, pero si que añaden nuevas librerías que exponen objetos que podemos usar en nuestra aplicación...

Uno de esos objetos es el objeto Database, el cual se usará para "mantener" una referencia a la base de datos, con la cual podremos abrir recordsets que nos permitirán, entre otras cosas, introducir y modificar los datos de cualquier tabla incluida en la base de datos a la que queramos acceder...

¿Qué es un Recordset?Según la ayuda de Visual Basic, "Un objeto Recordset representa los registros de una tabla o los registros del resultado de ejecutar una consulta". Una consulta es... eso... una consulta... una especie de búsqueda avanzada, en la que podemos indicar varios criterios de búsqueda... aunque también, como verás pronto, es algo más sencillo que todo eso. No te preocupes que veremos algunos ejemplos de "consultas".

Page 15: Bases de Datos usando DAO

Para poder manejar los objetos Database y Recordset, hay que crear unas variables para dichos objetos, por tanto en la sección de declaraciones del formulario (General/Declaraciones), añade estas líneas:

Option Explicit

Private db As DatabasePrivate rs As Recordset 

De esta forma tendremos una variable llamada db que apuntará al objeto Database y otra, llamada rs, que apuntará a un objeto del tipo Recordset.En el evento Form_Load asignaremos los "objetos reales" a esas dos variables.Para poder abrir la base de datos, necesitamos saber el path en el que se encuentra dicha base de datos, para ello vamos a crea una constante, en la cual tendrás que indicar el path correcto, es decir, el sitio exacto en el que se encuentra la base de datos, en nuestro caso será BIBLIO.MDB, la base de ejemplo que se incluye con Visual Basic.

Const sPathBase As String = "C:\Program Files\Microsoft Visual Studio\VB98\BIBLIO.MDB"

A continuación abrimos la base de datos usando la función OpenDatabase, la cual devuelve un objeto de la base de datos recién abierta, uno de los parámetros que espera recibir dicha función es el path de la base de datos que queremos abrir, en nuestro ejemplo usaremos el contenido de la constante anterior: sPathBase.

 ' Crear el objeto de base de datosSet db = OpenDatabase(sPathBase)

A continuación creamos el objeto recordset a partir de una "consulta" realizada a la base de datos, en este caso lo que queremos "consultar" son TODOS los campos de la tabla Authors:

 ' Crear el recordset con la tabla que queremos manipularSet rs = db.OpenRecordset("SELECT * FROM Authors", dbOpenDynaset)

La constante dbOpenDynaset le indica al método OpenRecordset que lo que queremos asignar a la variable rs, (de tipo Recordset), es del tipo Dynaset, este tipo de recordset permite mostrar y modificar los datos asignados a dicho recordset; además de este tipo de recordset, existen otros los cuales sólo se pueden usar para "recorrer" los datos o mostrarlos, si así lo prefieres, pero no permiten modificarlos, ese tipo de recordset también lo veremos en esta misma entrega.

Una vez que tenemos la variable rs, podemos acceder al contenido de la tabla Authors tal y como lo haciamos antes con el control Data. Para que te hagas una idea, rs tendrá el mismo funcionamiento que el que tenía Data1.Recordset en los ejemplos de las entregas anteriores sobre acceso a datos, en particular las entregas 34 y 35.

Como no tenemos un control data, el cual nos permitía movernos por los diferentes registros de la tabla, en el formulario hay cuatro botones, que se usarán para esa tarea: movernos tanto al primero, anterior, siguiente o último registro, el código para hacerlo es el que te muestro a continuación:

Page 16: Bases de Datos usando DAO

Private Sub cmdMover_Click(Index As Integer) On Error Resume Next ' ' Cuando las propiedades BOF y EOF dan como resultado TRUE, ' es que no hay datos, por tanto, salir del procedimiento If rs.BOF = True And rs.EOF = True Then Exit Sub End If ' ' Mover al registro indicado según el botón pulsado If Index = 0 Then ' Al primero rs.MoveFirst ElseIf Index = 1 Then ' Al anterior rs.MovePrevious ElseIf Index = 2 Then ' Al siguiente rs.MoveNext ElseIf Index = 3 Then ' Al último rs.MoveLast End If ' ' Si estamos antes del primero. mover al primero If rs.BOF Then rs.MoveFirst ' Si estamos después del último, mover al último ElseIf rs.EOF Then rs.MoveLast End If ' Si no se ha producido error, mostrar los datos If Err = 0 Then MostrarRegistro End If ' Err = 0End Sub

Lo primero que hacemos es comprobar si hay datos en el recordset, para ello comprobamos que ni BOF ni EOF den como resultado un valor verdadero. Cuando BOF es True, significa que el recordset está "antes" del primer registro, por otro lado EOF será True cuando estemos después del final de los registros. Cuando estas dos propiedades devuelven un valor verdadero, es que no hay datos en el recordset.

A continuación movemos el "puntero" del recordset al registro indicado, según el valor de Index sabremos que botón se ha pulsado y por tanto que "acción" tenemos que elegir. En los comentarios puedes ver qué valor corresponde con cada movimiento.

Como es posible que el usuario pulse en el botón anterior o siguiente después de estar al principio o al final respectivamente, tenemos que "controlar" si ya estamos al principio o al final del recordset para posicionarnos en el registro adecuado.

Por último, si todo ha ido bien, (no se ha producido un error), llamamos al procedimiento que muestra el contenido del registro activo en las cajas de texto.Esto último lo hace el procedimiento MostrarRegistro, cuyo código es el siguiente:

Page 17: Bases de Datos usando DAO

Private Sub MostrarRegistro() ' Mostrar los datos del registro actual ' A este procedimiento hay que llamarlo cada vez que ' queramos mostrar los datos del registro actual. With rs Text1(0) = .Fields("Au_ID") Text1(1) = .Fields("Author") Text1(2) = .Fields("Year Born") End WithEnd Sub

Si le echas un vistazo al código de las pruebas con el control Data, notarás que no era necesario llamar expresamente a un procedimiento para que los datos se mostraran, esto era así porque el propio datacontrol se encargaba de actualizar la información en los controles que tenía "enlazados", pero ahora no tenemos un control que "automatice" esta tarea, así que, tenemos que hacerlo por nuestros medios... por suerte no es tan difícil.

Ahora vamos a ver los procedimientos de Añadir un nuevo registro, actualizar uno ya existente y eliminar el registro actual. En el propio código encontrarás la explicación de que es lo que hace cada línea usada.

El código de Añadir un nuevo registro:

Private Sub cmdAdd_Click() ' Añadir un nuevo registro With rs .AddNew ' Añadimos algún texto, para saber que es un nuevo dato .Fields("Author") = "Nuevo Autor" ' Actualizamos los datos, para que se graben en el recordset .Update End WithEnd Sub

El código de Actualizar el contenido de las cajas de texto en el recordset:

Private Sub cmdActualizar_Click() ' Guardar el contenido de las cajas de texto With rs ' Antes de actualizar los datos del recordset, ' hay que ponerlo en modo edición .Edit ' Este campo es autonumérico, así que no asignarlo '.Fields("Au_ID") = Text1(0) + 0 ' Añadimos una cadena vacía al final ' ya que si Text1(1) está vacío, se asignará un valor NULL y dará error .Fields("Author") = Text1(1) & "" ' Idem con el año de nacimiento, pero como es numérico, se sumará 0 .Fields("Year Born") = Text1(2) + 0 ' Actualizar los datos en el recordset .Update

Page 18: Bases de Datos usando DAO

End WithEnd Sub

Y por último el código para eliminar un registro... como siempre, borrar es muy fácil...

Private Sub cmdBorrar_Click() ' Borrar el registro actual ' Se comprueba que haya algún registro activo, ' para ello se comprueba que no hayamos pasado del principio o el final del Recordset ' ' Comprobar que hay registros, porque si no hay, dará error If Not (rs.EOF Or rs.BOF) Then ' Eliminar el registro actual rs.Delete ' ' Movemos al primer registro cmdMover_Click 0 End IfEnd Sub

Bien, básicamente estas tareas son prácticamente iguales a las usadas con el datacontrol, con la salvedad de que hay que mostrar los datos cuando se cambia el registro activo.Ahora veremos el código usado para buscar los datos, el cual es también prácticamente lo mismo que cuando se tenía el datacontrol. Fíjate que la única diferencia es que en lugar de usar la propiedad Recordset del datacontrol, se usa el recordset "cargado" con los datos y que está contenido en la variable rs.

Este es el código de buscar y buscar siguiente, para lo cual usamos los métodos FindFirst y FindNext respectivamente.

Private Sub cmdBuscar_Click() ' Buscar el primer registro que coincida con el dato buscado BuscarEnd Sub

Private Sub cmdBuscarSig_Click() ' Buscar el siguiente 'Buscar Siguiente:=True Buscar TrueEnd Sub

Private Sub Buscar(Optional ByVal Siguiente As Boolean = False) ' Procedimiento para buscar el dato indicado (18/Ene/01) ' Si Siguiente = True, se busca a partir del registro activo Dim nReg As Long Dim sBookmark As String Dim sBuscar As String ' ' Iniciamos la detección de errores On Error Resume Next '

Page 19: Bases de Datos usando DAO

' Buscar la primera coincidencia en el recordset del Data1 If Option1.Value Then ' Convertir el contenido de TextBox en un número nReg = Val(Text2) ' en el campo Au_ID sBuscar = "Au_ID = " & nReg End If If Option2.Value Then ' en el campo Author sBuscar = "Author Like '" & Text2.Text & "'" End If ' With rs ' Guardar la posición anterior, por si no se halla lo buscado... sBookmark = .Bookmark ' If Siguiente = False Then ' Buscar desde el principio .MoveFirst .FindFirst sBuscar Else ' Busca a partir del registro actual .FindNext sBuscar End If ' Devolverá un error si no se halla lo buscado ' aunque no siempre es así... If .NoMatch Then Err.Clear MsgBox "No existe el dato buscado o ya no hay más datos que mostrar." ' Posicionar el recordset en la posición guardada .Bookmark = sBookmark End If ' Mostrar los datos del registro actual MostrarRegistro End WithEnd Sub

¿Cómo realizar consultas con DAO?

Ya hemos visto cómo introducir y modificar registros, también hemos visto cómo buscar un dato y seguir mostrando el resto de las coincidencias que se vayan produciendo. Pero hay ocasiones en las que a veces es necesario poder ver TODO el resultado de la búsqueda, incluso a veces nos interesa buscar más de un dato a la vez. Eso mismo se puede hacer con FindFirst y FindNext, es decir, podemos buscar en más de un campo del mismo registro el dato o datos que nos interesa a un mismo tiempo. Pero además de usar recordsets de sólo lectura, podemos acelerar esa tarea de "obtener" la información que queramos realizando consultas en lugar de ir buscando uno por uno los datos. Independientemente de cómo hagamos la consulta, siempre nos quedará el recurso de poder usar los métodos FindXXX para buscar a su vez datos dentro del resultado de la consulta, ya que al fin y al cabo el resultado de dicha consulta se almacena en un objeto recordset... ¡que lio! ahora veremos con ejemplos cómo funciona todo esto.

Para mostrar el resultado de la "búsqueda" o consulta, vamos a usar un control ListView.

Page 20: Bases de Datos usando DAO

Para añadir un control ListView a nuestro proyecto, primero hay que "añadir" el control a la barra de herramientas de Visual Basic, para ello, selecciona la opción Componentes del menú Proyecto y del cuadro de diálogo que te muestra, selecciona Microsoft Windows Common Controls, (pude que a continuación de este nombre te muestre la versión de Visual Basic, en mi caso, me muestra 6.0, pero también la 5.0 (SP2), ya que tengo instalado esas dos versiones de VB.Una vez que has pulsado en Aceptar, verás que se han añadido nuevos controles a la barra de herramientas (ToolBox), selecciona el que representa al Listview y añadelo al formulario, mediante código configuraremos la apariencia.Si quieres puedes crearte un nuevo proyecto para esta "segunda" prueba, ya que, además de añadir el ListView, también vamos a quitar los botones de búsqueda, porque no tiene sentido tenerlos... al menos para el propósito de este ejemplo.El aspecto del formulario sería el siguiente:

El aspecto, en tiempo de diseño, del segundo formulario

El código para configurar el ListView en tiempo de ejecución para mostrar la información de la tabla Authors de la base de datos Biblio.mdb lo pondremos en el evento Form_Load y es el siguiente:

With ListView1 ' El tipo de Listview que queremos es del tipo "reporte" .View = lvwReport ' Que muestre las líneas de separación entre datos .GridLines = True ' Que no se puedan modificar los datos del listview .LabelEdit = lvwManual ' Añadimos las cabeceras

Page 21: Bases de Datos usando DAO

.ColumnHeaders.Add , , "Au_ID", 900 .ColumnHeaders.Add , , "Autor", 2700 .ColumnHeaders.Add , , "Año nacimiento", 1500, lvwColumnRight End With

Ahora la búsqueda sólo se hará por el nombre del autor y se mostrarán en la lista todos los autores que coincidan con los datos que queremos buscar. El código del botón Buscar sería el siguiente:

Private Sub cmdBuscar_Click() ' Mostrar los datos en el listview Dim sBuscar As String Dim tRs As Recordset Dim tLi As ListItem ' ' Formar la cadena de la consulta: ' Se busca por el nombre del autor y se muestran clasificados por el nombre sBuscar = "SELECT * FROM Authors WHERE Author LIKE '" & Text2 & "' ORDER BY Author" ' Creamos un recordset del tipo "estático", el cual no es modificable ' para poder modificarlo, tendría que ser del tipo dbOpenDynamic Set tRs = db.OpenRecordset(sBuscar, dbOpenSnapshot) ' Comprobar que hay datos en el recordset With tRs ' Si no hay datos... If (.BOF And .EOF) Then MsgBox "No se han encontrado los datos buscados" Else ' Mostrar los datos hallados ListView1.ListItems.Clear .MoveFirst Do While Not .EOF Set tLi = ListView1.ListItems.Add(, , .Fields("Au_ID") & "") tLi.SubItems(1) = .Fields("Author") & "" tLi.SubItems(2) = .Fields("Year Born") & "" .MoveNext Loop End If End WithEnd Sub

En otra ocasión veremos cómo "diseñar" un formulario para consultas con distintas opciones de búsqueda, así como para búsqueda en múltiples campos.

En la próxima entrega veremos el código que habría que usar para hacer esto mismo pero usando ADO.

Así que, paciencia y a ser buenos.

Nos vemosGuillermo

Page 22: Bases de Datos usando DAO