Bueno, pues ya has visto como funcionan y podemos utilizar los DataControls.
Ahora vamos a dar un paso adelante, y vamos a aprender a manejar los Recordsets:
.jpg)
Habiamos visto que nosotros utilizabamos un DataControl para poder acceder a los datos que teniamos almacenados en memoria en un recordset que se creaba automaticamente cuando nosotros poniamos el nombre de la tabla del DataControl, y le deciamos de que tabla o consulta SQL queriamos que se cogiesen los datos para ese DataControl.
Lo que vamos a hacer ahora es crear dos variables especiales que existen a partir de Visual 4, y que puede contener Bases de Datos y Registros de una tabla de base de datos.
Es decir, que hay un tipo especial de variables que en vez de ser Integer, Boolean o String, son de tipo "DataBase", y pueden "contener" una base de datos, o mas bien el nombre y path de una base de datos, y luego hay otro tipo de variables que son de tipo "Recordset", y en ellas podremos almacenar tablas de datos, con lo que el esquema anterior se quedaria de la siguiente manera:

Basicamente no hay ninguna diferencia encuanto al manejo de los datos respecto a como se hacen con el DataControl, salvo que ahora estamos trabajando directamente sobre la tabla cargada en memoria sin necesidad de un intermediario como era el DataControl.
Pero bueno, es un poquito mas complicado.
En el DataControl, para que funcionase, debiamos rellenar dos propiedades fundamentales del mismo, que eran DataBaseName, y DataRecordSource, en una se le daba el nombre de la base de datos que ibamos a manejar, y en la otra se le decia de que tabla o consulta SQL se iban a coger esos datos.
Bueno, eso ahora se desglosa en cuatro lineas de codigo:
Dim dbBaseDatos as DataBase
Dim rsIngredientes as Recordset
Set dbBaseDatos = OpenDataBase ("C:\Recetas\Recetas.mdb")
Set rsIngredientes = dbBaseDatos.OpenRecordSet ("SELECT * FROM Ingredientes")
En las dos primeras, lo unico que hacemos, es definir dos variables, una de tipo DataBase, que es la que va a contener el path de la base de datos que vamos a utilizar, pero que no puede ser String, porque necesitamos decirle que va a ser una base de datos.
Y la segunda variable es de tipo Recordset , es decir que es como si fuese una tabla en blanco que nosotros creamos contra la base de datos que hayamos especificado en la primera variable.
Ya tenemos definidas las dos variables, ahora nos queda darle los valores, que es lo que hacemos en las lineas 3 y 4.
En la linea 3, inicializamos la variable BaseDatos, con la base de datos que vamos a utilizar, y en la segunda inicializamos la variable rsIngredientes para que coja todos los valores de la tabla ingredientes.
Dos puntualizaciones:
Yo le he dado los nombres a las variables como : dbBaseDatos, y rsIngredientes.
Las dos letras que preceden al nombre, no son necesarias, simplemente se las he puesto por la politica de prefijos, para saber que una es de tipo BaseDatos (db), y la otra es de tipo Recordset (rs).
Y en segundo lugar, he utilizado una sentencia SQL para decirle de donde queria yo que me cogiese los datos, pero podria haber hecho lo siguiente y hubiese funcionado igualmente:
Set rsIngredientes = dbBaseDatos.OpenRecordSet ("Ingredientes")
Es decir, dandole directamente el nombre de la tabla en vez de una sentencia SQL.
Te habras dado cuenta de que las lineas 1 y 3, equivalen a la propiedad DataBaseName del DataControl:
Dim dbBaseDatos as DataBase
Set dbBaseDatos = OpenDataBase ("C:\Recetas\Recetas.mdb")
Y las filas 2 y 4, equivalen a la propiedad RecordSource del DataControl:
Dim rsIngredientes as Recordset
Set rsIngredientes = dbBaseDatos.OpenRecordSet ("SELECT * FROM Ingredientes")
A partir de aqui, nosotros podriamos utilzar esa variable recordset, como si de un DataControl se tratase, pero ahora tendriamos que escribir lo siguiente:
Intstrucciones de movimiento:
rsIngredientes.MoveFirst
Nos movemos al primer registro del recordset Ingredientes
rsIngredientes.MoveLast
Nos movemos al último registro del recordset Ingredientes
rsIngredientes.MovePrevious
Nos movemos al registro anterior del recordset Ingredientes
rsIngredientes.MoveNext
Nos movemos al registro siguiente del recordset Ingredientes
Instrucciones de busqueda:
rsIngredientes.FindFirst Condicion
Busca el primer registro que cumpla una condicion
rsIngredientes.FindNext Condicion
Busca el siguiente registro que cumpla una condicion
Acceso a los datos del recordset:
Nombre1 = rsIngredientes.Fields ("Nombre")
Metemos el contenido del campo
Nombre2 = rsIngredientes!Nombre
Nombre en la variable Nombre1
Como ves, la unica diferencia es que cambiamos "Data1.Recordset", por el nombre del recordset que hemos creado.
Para que te quede mas claro, vamos a hacer un ejemplo:
Vamos a hacer una pantalla como la siguiente en la que se nos presenten los datos de los distintos ingredientes que tenemos, pero sin utilizar un DataControl, sino que crearemos y utilizaremos un recordset propio.
La pantalla es la siguiente:

Bueno, en primer lugar añadiremos los controles a la pantalla, y yo les he llamado:
TxNombre, TxTipo, TxPrecio, TxEmbalaje, BtAnterior, BtSiguiente
Paso 1
Empezaremos seleccionando la base de datos que vamos a utilzar, y diciendo que registros vamos a utilzar. Si tuviesemos un DataControl, utilizariamos las dos propiedades que ya conocemos "DataBaseName", y "RecordSource". Pero hemos dicho que vamos a utilzar variables, por lo que deberemos definirlas.
Nos encontramos con el problema de localidad de las variables, es decir, que si yo las variables las defino por ejemplo en el Form_Load, solo van a valer en el momento en el que se cargue el formulario, y luego no voy a poder utilizarlas una vez que el formulario ya haya sido cargado. Es una definicion que se nos queda corta para lo que necesitamos.
Podriamos pensar en hacer un modulo *.BAS y de esta forma ya nos valdria para todo el proyecto, pero este caso quiza sea una definicion demasiado amplia, pues solo vamos a utilizar este recordset en este Form, y no en ningun otro.
Asi que la solucion idonea en este momento parece realizar la definicion de las dos variables en el lugar de definicion de variables a nivel de formulario:

Bueno, ya tenemos definidas las dos variables, una para abrir la base de datos, y otra para abrir una tabla.
Pero nos queda abrir esas tablas, y eso deberiamos hacerlo en este caso en el momento en que se cargue el formulario:

Primero abrimos la base de datos diciendole donde esta situada en el disco duro, y luego abrimos una variable Recordset rsIngredientes, en la que le decimos los registros que queremos que se recojan en esa variable, que en este caso son todos los de la tabla ingredientes.
Y luego hacemos una llamada a una funcion que se llama PresentaDatos, y que lo que va a hacer es coger los datos del registro actual del recordset rsIngredientes, y presentarlos cada uno en la caja de texto que le corresponde si es que los campos no estan vacios, y si estan vacios entonces los rellena con "nada".
Debemos controlar si los campos estan rellenos o vacios, porque no podemos asignar a una caja de texto el valor NULL, que es el que tiene el campo si es que no tiene datos metidos.
La funcion seia la siguiente:
Private Function PresentaDatos()
If Not rsIngredientes.EOF And Not rsIngredientes.BOF Then
TxNombre.Text = rsIngredientes!Nombre
TxTipo.Text = rsIngredientes!Tipo
If Not IsNull(rsIngredientes!Precio) Then
TxPrecio.Text = rsIngredientes!Precio
Else
TxPrecio.Text = </P>
<P>End If</P>
<P>If Not IsNull(rsIngredientes!embalaje) Then</P>
<P>TxEmbalaje.Text = rsIngredientes!embalaje</P>
<P>Else</P>
<P>TxEmbalaje.Text =
End If
End If
End Function
Esta linea de la funcion anterior
If Not rsIngredientes.EOF And Not rsIngredientes.BOF Then
significa que "Si no es el primer registro del recordset rsIngredientes (BOF), y no es tampoco el ultimo (EOF) entonces puede hacer el resto de la funcion, que es rellenar cada Caja de Texto con su valor correspondiente.
Bueno, ahora solo queda definir el codigo que se va a ejecutar cuando se pulse cualquiera de los dos botones, que seria el siguiente:
Private Sub BtAnterior_Click()
If Not rsIngredientes.BOF Then
rsIngredientes.MovePrevious
PresentaDatos
End If
End Sub
Private Sub BtSiguiente_Click()
If Not rsIngredientes.EOF Then
rsIngredientes.MoveNext
PresentaDatos
End If
End Sub
Controlando siempre que no se me vaya mas alla del principio o de los datos almacenados en el recordset.
Bueno, solo nos queda por comentar una ultima cosa, y es que este tipo de variables, ya sean de Bases de Datos (Database), o Recordsets, una vez que no van a ser utilzados mas, deben de ser cerrados, porque sino vamos a tener un monton de tablas y bases de datos cargadas en memoria que no necesitaremos para nada.
Para hacer esto, en este caso, podriamos añadir un boton mas al formulario que fuese BtSalir, en el cual haremos que se cierre la base de datos y el recordset, y que luego se termine la aplicacion.
El codigo seria el siguiente:
Private Sub BtSalir_Click()
rsIngredientes.Close
dbBaseDatos.Close
End
End Sub
Bueno, este ejemplo nos sirve para aprender a generar una variable de tipo Recordset, pero realmente estas variables, muy rara vez se definen a nivel de formulario, sino que se crean y se cierran a nivel de funciones concretas.
Por ejemplo, en el caso de la pantalla en la que presentabas datos de dos tablas distintas, una de Recetas, y otra de Ingredientes, se podria haber resuelto de una forma muy sencilla por medio de una variable de tipo recordset que nos simplificaria mucho la instruccion SQL. Seria algo asi:

Al hacer click sobre una receta, cogemos el contenido del campo CodigoPlato y Receta, que son los que me la relacionan con la tabla de Ingredientes por Receta, y con esos datos recogidos, metemos en un recordset, el CodigoPlato, Nreceta de la tabla IngxReceta, y todos los datos de la tabla Ingredientes, relacionados por un INNER JOIN.
Puedes intentar hacerlo asi para practicar.
Solo un detalle, no se puede asociar un DBGrid a una variable Recordset, asi que tendrias que crear una tabla con SQL en la base de datos con todos los registros del Recordset , y asociar el DBGrid de Ingredientes a esa tabla recien creada.
Pero eso es otra historia, y debe ser contada en otro momento.... (en el siguiente capitulo: Ampliacion de SQL)