Sei sulla pagina 1di 25

CURSO DE VB

CAPTULO 111

ndice de contenido
OBJETOS DE ACCESO A DATOS (II)...............................................................................................2
RECORDSET..................................................................................................................................2
LA MANERA MS FCIL DE ACCEDER A UN RECORDSET: CLONARLO........................3
UN POCO DE TEORA..................................................................................................................5
ABRIR UN RECORDSET PARA CONSULTAR UN DATO........................................................6
RECORRER UN CONJUNTO DE REGISTROS..........................................................................7
MODIFICANDO UN REGISTRO..................................................................................................9
MODIFICANDO TODOS LOS REGISTROS.............................................................................10
Modificando todos los registros pero con ms de un campo....................................................11
Consultando una consulta.........................................................................................................12
Consultando una consulta que an no existe.............................................................................14
Error porque el valor no existe?.........................................................................................15
BSQUEDA RPIDA: Seek........................................................................................................17
AADIENDO UN REGISTRO....................................................................................................18
UNOS PREPARATIVOS NECESARIOS.....................................................................................19
EL EJEMPLO FINAL: UN MIX DE TODO LO APRENDIDO...............................................21
Cmo sera nuestra SQL...........................................................................................................21
ESTRUCTURACIN DEL CDIGO......................................................................................22
DESARROLLANDO EL CDIGO.........................................................................................22
UNAS PALABRAS FINALES......................................................................................................25

1 La BD donde estn los ejemplos de este captulo os la podis bajar aqu.

1
Vistame en http://siliconproject.com.ar/neckkito/
OBJETOS DE ACCESO A DATOS (II)
En el captulo anterior hemos visto el mtodo de acceso a
datos DAO. Sin embargo, nos faltaba algo.

Ese algo es examinar con detenimiento el mundo de los


recordset con DAO. Y a eso nos vamos a dedicar
inmediatamente.

Seguiremos manejando la BD de pruebas que comenzamos


a confeccionar en dicho captulo, por lo que se har
referencia, lgicamente, a elementos que ya creamos en su
momento.

Manos a la obra.

RECORDSET
Recordset, recordset... potito palabro. Access nos aclara qu es un recordset de la siguiente
manera:

<<Un objeto Recordset representa los registros de una tabla base o los registros resultantes
de la ejecucin de una consulta>>

Bueno... Ahora todos podemos presumir de que ya sabemos qu es un recordset, verdad? Je,
je...

Por ahora, lo que tenemos claro es que es un objeto, y, como tal, tiene sus propiedades y
mtodos, y es manipulable (os suena la frase?)

Si abrimos una tabla o de una consulta podemos ver los datos que hay en ellas, organizados
en registros. El conjunto de esos registros constituira un recordset. Pero la idea de recordset
lleva implcita algo ms, algo que podramos llamar inmaterial.

Lo que voy a comentaros a continuacin es algo que est totalmente alejado de tecnicismos y
teora y, en el fondo, es una reflexin ma de carcter personal. Sin embargo, considero que
tras su lectura todo el mundo debera tener una idea ms que clara de lo que es un recordset.

Vamos a hacer un smil, ponindonos un poco filosficos: abrimos una tabla (con datos, claro),
miramos intensamente la pantalla y cerramos los ojos. Si queremos podemos ver, en nuestra
mente, reproducida esa tabla con su informacin. Es ms, podemos centrarnos en un registro
e imaginar que ese registro desaparece. O nos centramos en un registro, siempre en nuestra
mente, y ms en concreto en un campo y un dato. Y ah donde pone electricista (por
ejemplo) nos imaginamos que pone fontanero. Y , por nuestra voluntad, automticamente
slo vemos los registros en los que en ese campo hay el valor fontanero, y los otros
desaparecen.

Pues Access sera como nosotros mismos, y los recordset seran esa imagen que tenemos en
el cerebro. As como nosotros podemos imaginar que desaparecen registros Access puede
hacer desaparecer registros, aadir de nuevos, sustituir los existentes, aadir ms campos,
etc.

Dnde est fsicamente ese recordset que maneja Access? Pues para nosotros no est, en el
sentido que no podemos verlo en la aplicacin. Slo podemos tener acceso visible al mismo
cuando Access escribe los resultados en una tabla o consulta, o, a veces, ni siquiera eso,

2
Vistame en http://siliconproject.com.ar/neckkito/
puesto que nos informa a travs de un MsgBox.

Ni que decir tiene que nosotros manejamos las acciones


que se deben desarrollar sobre el recordset, pero es Access
quien, en ese limbo, los ejecuta y despus los muestra de
la manera que nosotros le hemos pedido.

Evidentemente he recurrido a una imagen onrica para


describiros un recordset, pero, en el fondo, lo que sucede
dentro de Access al manejar un recordset es lo que os
acabo de explicar. De hecho, cuando programemos acciones
sobre un recordset involuntaria o voluntariamente
tendremos que imaginarnos esa accin imaginaria que se
ejecutar con el fin de conseguir el objetivo deseado.

Y despus de este ambiente chillout en que nos hemos sumergido vamos a ver un par de cosas
sobre los recordset.

LA MANERA MS FCIL DE ACCEDER A UN RECORDSET: CLONARLO


Pero antes, os explico qu vamos a hacer:

El cdigo que vamos a programar nos solicitar un DNI. Acto seguido clonar el recordset de la
tabla. Qu significa eso? Que por una parte tendremos el recordset de la tabla y por otro
tendremos una copia de dicho recordset. En definitiva, que estaremos operando con dos
recordsets: original y copia.

Por qu hacemos eso? Pues porque nos es ms cmodo, para la operacin que vamos a
realizar, trabajar sobre un recordset inmaterial que no directamente sobre la tabla. Y ello es
as porque el recordset copia tiene una serie de propiedades y mtodos que podemos
manipular a nuestro antojo.

Realizamos las operaciones que necesitamos sobre el recordset copia y conseguimos un


resultado. Y a continuacin lo que vamos a hacer es aplicar dichos resultados sobre el
recordset original. Y como, por decirlo de alguna manera, el recordset original es el que
tenemos en pantalla, podremos ver los resultados tambin en pantalla.

Nos acordamos cuando, en el primer apartado, yo hablaba de nuestra mente? Pues el clon
del recordset que hemos creado se aloja en memoria del ordenador, lo que implica que est
consumiendo un espacio. Por ello, una vez obtenido el resultado, y dado que ya no
necesitamos ms ese clon, podemos cerrarlo, primero, y eliminarlo, despus, de la memoria,
tal y como aprendimos en el captulo anterior (nos acordamos de Close y de =Nothing?).
As, tal y como lo hemos creado, lo hacemos desaparecer.

Vimos este sistema en el captulo dedicado a filtros, por lo que ya os debera sonar todo lo
que vamos a ver. Pero esta vez el enfoque de la explicacin ser desde el punto de vista de
DAO.

Si abrimos nuestro formulario FTrabajadores le aadimos un botn en la cabecera del


formulario, y ese botn ser el que programaremos.

Ahora s estamos en condiciones de ver el cdigo (no incluye elementos de control):

.
Private Sub cmdRecordsetClon_Click()
'Declaramos las variables

3
Vistame en http://siliconproject.com.ar/neckkito/
Dim nDNI As Long
Dim filtro As String
Dim rst As Recordset
'Solicitamos al usuario que introduzca un DNI
nDNI = InputBox("Introduzca un DNI a buscar", "DNI")
'Creamos el filtro
filtro = "[DNI]=" & nDNI
'Clonamos el recordset
Set rst = Me.Recordset.Clone
'Manipulamos el recordset del clon para buscar un DNI a
travs
'del mtodo Recordset.FindFirst()
rst.FindFirst filtro
'Cuando lo encuentra aadimos un marcador a nuestro clon para
'"fijar" el registro que cumple con el filtro a travs de la propiedad
'Recordset.Bookmark
'Traspasamos ese marcador al recordset original. De esta manera
'en pantalla nos situaremos en el registro que cumple con el filtro
Me.Bookmark = rst.Bookmark
'Cerramos el recordset clon
rst.Close
'Lo eliminamos de memoria
Set rst = Nothing
End Sub

Si probamos el botn y buscamos un DNI veremos los resultados.

Fijmonos en un par de detalles:

Generalmente, si utilizamos el mtodo DAO, se define el recorset con el nombre de rst


Al declararlo como variable le decimos que va a ser un recordset: Dim rst As Recordset
Para crearlo utilizamos la estructura SET rst = xxx. Es decir, que para asignar valor a
variables las igualbamos directamente (i.e., DNI=123), mientras que para un recordset
debemos utilizar SET (de manera similar a cmo determinbamos dbs o tbl o fld).
Para llamar al recordset original del formulario (que es la tabla TTrabajadores)
utilizamos a nuestro viejo conocido ME. Con ello quiero decir que utilizamos el mismo sistema
que en un captulo anterior utilizbamos para llamar a formularios y subformularios.
Lo clonamos a travs de la estructura (os indico la estructura larga):

Forms!NombreForm.Recordset.Clone

A partir de ah, para referirnos a nuestro clon, siempre utilizaremos rst. (rst punto). Y
ya tenemos posibilidad, con esta nomenclatura, de actuar sobre sus propiedades y mtodos.
De hecho, primero actuamos sobre el mtodo FindFirst y despus actuamos sobre la propiedad
Bookmark.
En el ejemplo, el traspaso del resultado se produce a travs de la igualacin de la
misma propiedad (Me.Bookmark rst.Bookmark)
Para cerrar el recordset siempre utilizamos rst.Close
Para liberar memoria le tenemos que decir a Access que el recordset es nada. Ello lo
conseguimos a travs de la instruccin Set rst = Nothing

Siguiendo con este ejemplo, vamos a complicar el cdigo ligeramente. Qu pasa si el DNI
introducido y buscado no existe? Pues manipulamos otra propiedad del recordset. En este caso
la propiedad afectada es NoMatch. Como ya sabemos cmo actuar sobre ella (rst. +
propiedad) pues... la cosa est hecha.

4
Vistame en http://siliconproject.com.ar/neckkito/
El cdigo nos quedara as:

Private Sub cmdRecordsetNoExiste_Click()


'Declaramos las variables
Dim nDNI As Integer
Dim filtro As String
Dim rst As Recordset
'Solicitamos al usuario que introduzca un DNI
nDNI = InputBox("Introduzca un DNI a buscar", "DNI")
'Creamos el filtro
filtro = "[DNI]=" & nDNI
'Clonamos el recordset
Set rst = Me.Recordset.Clone
'Manipulamos el recordset del clon para buscar un DNI a travs
'del mtodo Recordset.FindFirst()
rst.FindFirst filtro
'Si no existe el DNI buscado tomamos una decisin a travs de un IF...END IF
If rst.NoMatch Then
MsgBox "El DNI buscado no existe en la base de datos", vbCritical, "NO EXISTE"
Else
'Si existe traspasamos el resultado al rst original
Me.Bookmark = rst.Bookmark
End If
'Cerramos y liberamos memoria
rst.Close
Set rst = Nothing
End Sub

Creo que no hace falta realizar ningn comentario. Deberamos ser capaces de entender el
cdigo perfectamente con todo lo que ya sabemos... je, je...

UN POCO DE TEORA
Vamos a relajar un poco los dedos, despus de tanto ejemplo, y vamos a darle al coco con
un poco de teora. Os aseguro que nos ser til para ms adelante.

Podemos abrir un recordset de cuatro maneras diferentes, cada una con sus caractersticas.
Vamos a verlas:

a) dbOpenTable

Este sistema nos permite abrir una tabla. La principal ventaja es que nos permite utilizar los
ndices de la tabla. Con este sistema de apertura podemos aadir o modificar los datos de la
tabla (a no ser que le indiquemos que la abra en modo slo lectura).

Tambin debemos tener en cuenta que este sistema no es aplicable si lo que tenemos son
tablas vinculadas. Ello nos implicara abrir el recordset con otro sistema.

b) dbOpenDynaset

Por Dynaset podramos entender la idea de hoja de respuestas dinmica. Este mtodo de
apertura representa el resultado de una consulta cuyos registros pueden actualizarse.

5
Vistame en http://siliconproject.com.ar/neckkito/
Dado que podemos realizar consultas sobre varias tablas una ventaja de este sistema es,
precisamente, el poder trabajar sobre los datos de varias tablas.

c) dbOpenSnapshot

Snapshot es sinnimo de slo lectura (instantnea, si nos


ponemos a traducir). Su efecto es como si abriramos una
consulta en ese modo slo lectura. De lo anterior
deducimos que su ventaja es la velocidad de procesamiento
(dado que Access no se debe preparar para recibir
rdenes para aadir o modificar registros -por decirlo de
alguna manera-).

d) dbOpenForwardOnly

Si volvemos a utilizar el traductor veremos que eso significa slo hacia adelante. Es decir, es
como si abriramos un snapshot (=slo lectura), pero slo podemos desplazarnos por los
registros hacia adelante. Si la caracterstica de dbSnapshot era la velocidad, pues la
caracterstica de dbOpenForwardOnly es la velocidad multiplicada.

Es interesante saber lo anterior dado que, segn la accin que necesitemos realizar sobre el
recordset (operar sobre l o slo consultarlo), podemos optimizar el funcionamiento del cdigo.

Tambin debemos tener en cuenta que hay propiedades y mtodos que funcionan con todos
los sistemas, pero hay otros que slo funcionan en unos pero no en otros. No os preocupis
pro eso porque los errores de cdigo nos advertirn inmediatamente de que utilizamos un
cuchillo para comer sopa.

Y como estoy seguro de que estamos ya saturados de tanta teora (je, je...) volvamos a
nuestra BD para poner en prctica esto que acabamos de entender.

ABRIR UN RECORDSET PARA CONSULTAR UN DATO


Vamos, en un formulario en blanco, a crear un botn que nos operar con un recordset para
mirar el nombre del primer trabajador de la tabla TTrabajadores.

El cdigo que deberamos emplear es el siguiente:

Private Sub cmdNombrePrimerTrabajador_Click()


'Declaramos las variables
Dim nomTrab As String
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
'Definimos las variables
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("TTrabajadores", dbOpenSnapshot)
'Nos movemos al primer registro
rst.MoveFirst
'Capturamos el nombre del trabajador
nomTrab = rst.Fields(1).Value
'Mostramos el MsgBox con la informacin
MsgBox "El primer trabajador se llama " & nomTrab, vbInformation, "INFO"
'Cerramos conexiones y liberamos memoria
rst.Close
dbs.Close

6
Vistame en http://siliconproject.com.ar/neckkito/
Set rst = Nothing
Set dbs = Nothing
End Sub

Vamos a ver cmo lo hacemos:

Declaramos la variable rst como DAO.Recordset


Al inicializarla utilizamos la siguiente estructura
Set rst = dbs.OpenRecordset(NombreTabla,
ModoApertura)

Recordando la teora aprendida hace unos instantes, el modo de apertura que hemos elegido
ha sido dbOpenSnapshot, porque slo nos interesaba mirar qu valor tena ese primer campo
del primer registro.

Para movernos al primer registro utilizamos rst.MoveFirst. Como podis imaginar, si


hubiramos querido mirar el nombre el ltimo trabajador hubiramos tenido que desplazar el
puntero del recordset al ltimo registro, a travs de rst.MoveLast.
Tras esto, tened en cuenta que podemos desplazarnos por los registros con:
MoveFirst
MoveLast
MovePrevious
MoveNext
Move
Para indicar el campo que queremos utilizar debemos decrselo al cdigo. Eso lo
hacemos a travs de rst.Fields(x), donde x es el nmero de campo.
Recordamos que el objeto Fields perteneca a una coleccin? Y recordamos que las
colecciones inician su conteo con cero, y no con uno?
Pues tras recordar esto tenemos, en la tabla TTrabajadores, lo siguiente:
Campo [DNI] Se correspondera con Fields(0)
Campo [Nombre] Se correspondera con Fields(1)
Campo [Sexo] Se correspondera con Fields(2)

Qu hacemos si no tenemos claro el nmero del campo? Podemos indicrselo al cdigo


directamente por su nombre.

As, podramos haber escrito

nomTrab = rst.Fields(Nombre).Value

RECORRER UN CONJUNTO DE REGISTROS


Para recorrer un conjunto de registros se suele utilizar, generalmente, el bloque DO
UNTIL...LOOP. Para poder seguir adelante debemos antes conocer dos propiedades:

BOF

Vendra a significar Begin Of Files. Lo que est indicando es que el puntero del recordset est
antes de la primera fila del recordset.

EOF

Vendra a significar End Of Files. Nos indica que el puntero del recordset se halla despus de la
ltima fila del recordset.

7
Vistame en http://siliconproject.com.ar/neckkito/
Si combinamos la idea del bloque DO UNTIL...LOOP con estas dos propiedades podemos ver
cmo le damos las instrucciones al cdigo para el recorrido del recordset.

Es decir, que si queremos empezar por el primer registro y


acabar en el ltimo debemos decir:

1.- Sitate en el primer registro


2.- Haz estas acciones hasta que llegues a la ltima de las
filas.

Y lo anterior, traducido a cdigo, sera:

rst.MoveFirst
Do Until rst.EOF
'Acciones a desarrollar
rst.MoveNext
Loop

Por el contrario, si lo que queremos es empezar en el ltimo registro y recorrer el recordset


hasta llegar al primero lo que deberamos escribir es:

rst.MoveLast
Do Until rst.BOF
'Acciones a desarrollar
rst.MovePrevious
Loop

Vamos a conseguir que el cdigo nos diga los nombres de los trabajadores de nuestra tabla.
As pues escribimos lo siguiente:

Private Sub cmdNombreTrabajadores_Click()


'Declaramos las variables
Dim nomTrab As String
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
'Definimos las variables
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("TTrabajadores", dbOpenSnapshot)
'Nos movemos al primer registro
rst.MoveFirst
'Hasta que no llegues al final del recordset, haz...
Do Until rst.EOF
nomTrab = rst.Fields(1).Value
MsgBox "Nombre trabajador: " & nomTrab, vbInformation, "NOMBRES"
'Nos movemos al siguiente registro
rst.MoveNext
If rst.EOF Then
MsgBox "Hemos llegado al final de la lista", vbExclamation, "FIN"
End If
Loop
'Cerramos conexiones y liberamos memoria

8
Vistame en http://siliconproject.com.ar/neckkito/
rst.Close
dbs.Close
Set rst = Nothing
Set dbs = Nothing
End Sub

Tras lo explicado no creo que tengis problemas para


entender el cdigo. Destacar que he aadido un bloque
IF...END IF, a todas luces innecesario (podramos haber
puesto directamente ese MsgBox tras el Loop) para que
pudierais ver en otro ambiente cmo podemos tambin
manejar estas propiedades del recordset que estamos
comentando.

MODIFICANDO UN REGISTRO
Vamos a abrir directamente la tabla y vamos a modificar el nombre del ltimo trabajador.
Vamos a cambiar Laura por Laurita.

Para modificar un registro debemos seguir la siguiente estructura:

Primero, indicar al cdigo que nos disponemos a realizar una edicin del registro
Segundo, indicar el campo que queremos y qu nuevo valor va a contener
Tercero, actualizar la informacin modificada en la tabla.

Eso lo conseguimos a travs de un bloque With...End With, de la siguiente manera:

With rst
.Edit
.Fields(x).Value = <NuevoValor>
.Update
End With

As pues, el cdigo para tener contenta a Laurita sera el siguiente:

Private Sub cmdCambiaNombre_Click()


'Declaramos las variables
Dim nomTrab As String
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
'Definimos las variables
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("TTrabajadores", dbOpenTable)
'Nos movemos al ltimo registro
rst.MoveLast
'Editamos el campo [Nombre] y cambiamos su valor
With rst
.Edit
.Fields(1).Value = "Laurita"
.Update
End With
'Mostramos un MsgBox de confirmacin

9
Vistame en http://siliconproject.com.ar/neckkito/
MsgBox "Cambios realizados correctamente", vbInformation, "OK"
'Cerramos conexiones y liberamos memoria
rst.Close
dbs.Close
Set rst = Nothing
Set dbs = Nothing
End Sub

Fcil, verdad? Fijaos que hemos tenido que abrir la tabla


con el sistema dbOpenTable para poder realizar la edicin
de datos; si la hubiramos abierto como dbOpenSnapshot
no nos lo hubiera permitido.

MODIFICANDO TODOS LOS REGISTROS


Si queremos modificar todos los registros deberemos recorrer todos los registros. Slo
tenemos que aplicar lo aprendido en dos apartados anteriores y unificarlo.

Supongamos que queremos que todos los nombres de los trabajadores estn en mayscula.
Esta operacin ya la sabemos hacer de lo aprendido en captulos anteriores. As pues os
animo a que, antes de mirar el cdigo que os pongo a continuacin, intentis programarlo
vosotros mismos, para ver dnde fallamos (si es que fallamos).

El cdigo que nos hara eso sera:

Private Sub cmdPasaAMay_Click()


'Declaramos las variables
Dim nomTrab As String
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
'Definimos las variables
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("TTrabajadores", dbOpenTable)
'Nos movemos al primer registro
rst.MoveFirst
'Hasta que no llegues al final del recordset, haz...
Do Until rst.EOF
With rst
.Edit
.Fields(1).Value = UCase(.Fields(1).Value)
.Update
End With
'Nos movemos al siguiente registro
rst.MoveNext
Loop
'Avisamos de que "la operacin" ha sido "todo un xito"
MsgBox "Datos actualizados correctamente", vbInformation, "OK"
'Cerramos conexiones y liberamos memoria
rst.Close
dbs.Close
Set rst = Nothing
Set dbs = Nothing
End Sub

10
Vistame en http://siliconproject.com.ar/neckkito/
Como vemos si analizamos el cdigo, con lo aprendido hasta ahora resulta muy fcil (s?)
adaptar el cdigo a nuestras necesidades. Ya comentaba en el captulo anterior que esto es
como un mecano: con las piezas correctas podemos construir una estructura segn
nuestras necesidades.

Si tuviera algo que destacar del cdigo es la manera en que


hemos manipulado el valor del campo, lo cual hemos hecho
de forma extraordinariamente directa. No hemos hecho:
Cojo el valor del campo
Lo transformo a maysculas
Indico el nuevo valor
sino que hemos hecho un tres-en-uno a travs de

.Fields(1).Value = UCase(.Fields(1).Value)

De todas maneras no os preocupis por esto, porque si habis conseguido el resultado


esperado (cambiar los nombres a maysculas), pues perfecto. La estructura anterior os saldr
sola cuando hayis realizado tres o cuatro cdigos (bueno... quiz algunos ms, pero pocos ;)

Modificando todos los registros pero con ms de un campo


Pongo este ejemplo a efectos slo clarificadores, para que podis ver cmo se hace. Pero no
hay ms secreto.

Eso s, aprovecharemos para ver el rst.Move

Vamos a modificar el valor del segundo registro, y nuestra Eva se va a convertir en Rambo.
Evidentemente, debemos cambiar tambin el sexo de nuestro Rambo, porque dejarlo como
Mujer sera... inconveniente?

El cdigo para ello sera:

Private Sub cmdCambiaVariosCampos_Click()


'Declaramos las variables
Dim nomTrab As String
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
'Definimos las variables
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("TTrabajadores", dbOpenTable)
'Nos movemos al segundo registro
rst.Move (1)
'Editamos el campo [Nombre] y el campo [Sexo] y cambiamos sus valores
With rst
.Edit
.Fields(1).Value = "RAMBO"
.Fields(2).Value = "Hombre"
.Update
End With
'Mostramos un MsgBox de confirmacin
MsgBox "Cambios realizados correctamente", vbInformation, "OK"
'Cerramos conexiones y liberamos memoria
rst.Close
dbs.Close

11
Vistame en http://siliconproject.com.ar/neckkito/
Set rst = Nothing
Set dbs = Nothing
End Sub

Fijaos en:

'Nos movemos al segundo registro


rst.Move (1)

Supongo que no hace falta que os recuerde que estamos en


una coleccin, y las colecciones comienzan el recuento por
cero, verdad? ;)

y fijaos en

With rst
.Edit
.Fields(1).Value = "RAMBO"
.Fields(2).Value = "Hombre"
.Update
End With

Simplemente remarcar que el .Edit edita todo lo que est a continuacin, hasta que damos la
orden de actualizar los datos (.Update). As, todos los campos que queramos modificar iran
ah dentro.

Consultando una consulta


Vamos a realizar la apertura de un recordset sobre una consulta. Para no ser tan repetitivos
con los ejemplos vamos a ver una utilidad que nos dir cuntos hombres y cuntas mujeres
nos devuelve la consulta.

S que alguien puede pensar: eso es un poco tontera, pero insisto en que lo que os intento
transmitir no es esto se hace as, sino que con todo lo que sabemos hasta ahora podemos
realizar muchas operaciones simplemente combinando cdigos o sistemas.

Si recordamos tenemos en nuestra BD una consulta llamada CTrabajadores, simple consulta de


seleccin que nos devuelve los mismos registros que la tabla TTrabajadores (y si no la
tuviramos la creamos y ya est).

El cdigo que podramos programar para conseguir lo que queremos sera, por ejemplo:

Private Sub cmdNumHM_Click()


'Declaramos las variables
Dim nM As Integer, nH As Integer
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
'Definimos las variables
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("CTrabajadores", dbOpenDynaset)
'Inicializamos los contadores
nM = 0
nH = 0
'Nos movemos al primer registro

12
Vistame en http://siliconproject.com.ar/neckkito/
rst.MoveFirst
'Iniciamos el proceso de recuento
Do Until rst.EOF
'Miramos el valor del campo sexo y sumamos una unidad
If rst.Fields("Sexo").Value = "Hombre" Then
nH = nH + 1
Else
nM = nM + 1
End If
'Nos movemos al siguiente registro
rst.MoveNext
Loop
'Mostramos los resultados
MsgBox "Hay " & nM & " mujeres y " & nH & " hombres", vbInformation, "RECUENTO"
'Cerramos conexiones y liberamos memoria
rst.Close
dbs.Close
Set rst = Nothing
Set dbs = Nothing
End Sub

Deberamos destacar de este cdigo las siguientes ideas:

Como abrimos una consulta pues debemos abrir el recordset con el mtodo
dbOpenDynaset (hubiramos podido utilizar un dbOpenSnapshot sin problemas). Lo que no
podramos utilizar es el mtodo dbOpenTable.

Si hubiramos utilizado este ltimo mtodo nos saldra un pedazo mensaje dicindonos:

Recordaros que podemos hacer referencia al campo que queremos capturar o bien por
su ndice o bien por su nombre. En este caso yo he utilizado el nombre
(rst.Fields("Sexo").Value)
El bloque IF...END IF nos examina el valor del campo y suma una unidad al contador
que corresponda. Sin problemas, supongo.
Por ltimo, ved que he declarado las variables nH y nM como Integer. Si nuestra BD
tuviera ms de 32.767 registros que cumplieran la condicin el cdigo nos dara error. En ese
caso recordad que deberamos declarar esas variables como Long (que tiene una capacidad
mayor).

13
Vistame en http://siliconproject.com.ar/neckkito/
Consultando una consulta que an no existe
Es en estos momentos tan duros de nuestro captulo
cuando empezamos a apreciar la importancia de las
consultas SQL.

Mediante una SQL podemos crearnos una consulta segn


nuestras necesidades, en tiempo de ejecucin, analizarla y
actuar en consecuencia.

Qu ventaja obtenemos de ello? Pues que no es necesario


llenar nuestra BD de consultas como objeto consulta para
poder acceder a ellas.

Para hacernos una idea es como si dijramos: necesito esto Y esto aparece por arte de
magia en nuestra mano Ya no lo necesito Y esto desaparece tambin como por arte de
magia.

Vamos a ver una consulta SQL muy simple, que nos filtrar un trabajador por DNI solicitado.
Como resultado obtendremos un MsgBox con la informacin de ese trabajador/trabajadora.

El cdigo sera:

Private Sub cmdDatosTrabSQL_Click()


'Declaramos las variables
Dim nDNI As Integer
Dim miSql As String
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
'Definimos la BD de trabajo
Set dbs = CurrentDb
'Solicitamos el DNI al usuario
nDNI = InputBox("Introduzca DNI", "DNI")
'Creamos la SQL
miSql = "SELECT TTrabajadores.* FROM TTrabajadores"
miSql = miSql & " WHERE TTrabajadores.DNI=" & nDNI
'Abrimos el recordset sobre la SQL
Set rst = dbs.OpenRecordset(miSql, dbOpenSnapshot)
'Mostramos la informacin
MsgBox "DNI: " & nDNI & vbCrLf & "Nombre: " & rst.Fields("Nombre").Value _
& vbCrLf & "Sexo: " & rst.Fields("Sexo").Value, vbInformation, "DATOS"
'Cerramos conexiones y liberamos memoria
rst.Close
dbs.Close
Set rst = Nothing
Set dbs = Nothing
End Sub

La mecnica es muy similar a la que hemos visto hasta ahora. Simplemente nuestro recorset
ha tomado los datos de una SQL.

Si analizamos esta SQL veremos que su estructura es:

SELECT
nombreTabla.nombreCampo

14
Vistame en http://siliconproject.com.ar/neckkito/
FROM
nombreTabla
WHERE
condicin

En este caso hemos utilizado el comodn asterisco, lo cual


quiere decir que seleccionamos todos los campos de la
tabla. Si slo nos hubieran interesado dos campos, por
ejemplo, hubiramos tenido que escribir:

SELECT TTrabajadores.DNI, TTrabajadores.Sexo FROM


TTrabajadores

Es decir, los campos separados por comas.

En cuanto al WHERE tened en cuenta que funcionan las mismas peculiaridades, segn el tipo
de campo, que comentbamos en los filtros. Es decir, en nuestro caso, al ser un dato tipo
numrico, el filtro ha sido directo ( WHERE TTrabajadores.DNI = & nDNI)

Si hubiramos filtrado por un valor de tipo texto deberamos haber encerrado la variable entre
comillas simples. Por ejemplo, as: WHERE TTrabajadores.Nombre=' & nom & '

Es importante que os fijis que entre las comillas y el WHERE hay un espacio. Como podis ver
la SQL es un String. Si no ponemos ese espacio la SQL nos quedara escrita as (por ejemplo):
SELECT TTrabjadores.* FROM TTrabajadoresWHERE TTrabajadores.DNI = 123

Y al entender la SQL que la tabla de origen se llama TTrabajadoresWHERE nos saltara error de
cdigo porque, evidentemente, esa tabla no existe.

Error porque el valor no existe?


Si probamos nuestro cdigo anterior y le indicamos, en el InputBox, un DNI que no est en la
tabla, qu ocurre?

Pues que obtenemos este precioso


mensaje:

Eso significa que nuestra SQL est


vaca porque no hay registros que
cumplan la condicin.

Cmo detectar el error? Hay varios


sistemas.

El primero es contar el nmero de


registros devueltos por la consulta. Si el nmero de registros devuelto es cero eso quiere decir
que no hay informacin.

La propiedad que nos indica el nmero de registros es Recordcount.

As, si reescribimos nuestro cdigo aadiendo unas lneas de cdigo que nos controlen lo
anterior podremos evitar dicho error.

El cdigo nos debera quedar as:

15
Vistame en http://siliconproject.com.ar/neckkito/
Private Sub cmdSQLSinDatos_Click()
'Declaramos las variables
Dim nDNI As Integer
Dim miSql As String
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
'Definimos la BD de trabajo
Set dbs = CurrentDb
'Solicitamos el DNI al usuario
nDNI = InputBox("Introduzca un DNI inexistente", "DNI")
'Creamos la SQL
miSql = "SELECT TTrabajadores.* FROM TTrabajadores"
miSql = miSql & " WHERE TTrabajadores.DNI=" & nDNI
'Abrimos el recordset sobre la SQL
Set rst = dbs.OpenRecordset(miSql, dbOpenSnapshot)
'Comprobamos que la consulta devuelve registros. Si no hay registros
'lanza un mensaje de advertencia y sale del proceso
If rst.RecordCount = 0 Then
MsgBox "No hay trabajadores con el DNI solicitado", vbCritical, "SIN DATOS"
Exit Sub
End If
'Si hay datos mostramos la informacin
MsgBox "DNI: " & nDNI & vbCrLf & "Nombre: " & rst.Fields("Nombre").Value _
& vbCrLf & "Sexo: " & rst.Fields("Sexo").Value, vbInformation, "DATOS"
'Cerramos conexiones y liberamos memoria
rst.Close
dbs.Close
Set rst = Nothing
Set dbs = Nothing
End Sub

Os he marcado en negrita las lneas de control para evitar sustos.

Otro sistema sera comprobar si el inicio del recordset y el final del recordset son coincidentes.
Si lo son es que no hay ningn registro entre ellos, ergo no hay informacin que mostrar. El
cdigo sera el siguiente:

Private Sub cmdSQLSinDatos2_Click()


'Declaramos las variables
Dim nDNI As Integer
Dim miSql As String
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
'Definimos la BD de trabajo
Set dbs = CurrentDb
'Solicitamos el DNI al usuario
nDNI = InputBox("Introduzca un DNI inexistente", "DNI")
'Creamos la SQL
miSql = "SELECT TTrabajadores.* FROM TTrabajadores"
miSql = miSql & " WHERE TTrabajadores.DNI=" & nDNI
'Abrimos el recordset sobre la SQL
Set rst = dbs.OpenRecordset(miSql, dbOpenSnapshot)
'Comprobamos que inicio del recordset y fin del recordset son
'coincidentes. Si lo son es que no hay datos.

16
Vistame en http://siliconproject.com.ar/neckkito/
If rst.BOF And rst.EOF Then
MsgBox "No hay trabajadores con el DNI solicitado", vbCritical, "SIN DATOS"
Exit Sub
End If
'Si hay datos mostramos la informacin
MsgBox "DNI: " & nDNI & vbCrLf & "Nombre: " &
rst.Fields("Nombre").Value _
& vbCrLf & "Sexo: " & rst.Fields("Sexo").Value,
vbInformation, "DATOS"
'Cerramos conexiones y liberamos memoria
rst.Close
dbs.Close
Set rst = Nothing
Set dbs = Nothing
End Sub

Os he marcado en negrita cmo seran las lneas de este control.

BSQUEDA RPIDA: Seek


Cuando hablbamos de clonar el recordset hemos visto el mtodo FindFirst. Sin embargo, si
sabemos que vamos a realizar la bsqueda sobre un campo indexado podemos utilizar el
mtodo Seek. La velocidad de proceso a travs de Seek es superior a FindFirst, por lo que
nuestras bsquedas darn resultados con mayor celeridad.

Si queremos realizar una bsqueda por DNI con este mtodo el cdigo sera:

Private Sub cmdSeek_Click()


'Declaramos las variables
Dim vDNI As Integer
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
'Definimos la BD de trabajo y el recordset
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("TTrabajadores", dbOpenTable)
'Solicitamos el DNI al usuario
vDNI = InputBox("Introduzca DNI", "DNI")
'Indicamos el ndice actual: clave primaria
rst.Index = "PrimaryKey"
'Buscamos
rst.Seek "=", vDNI
'Si el registro no existe avisamos y salimos del proceso
If rst.NoMatch Then
MsgBox "El DNI buscado no existe", vbCritical, "SIN DATOS"
Exit Sub
End If
'Mostramos los resultados
MsgBox "El DNI " & vDNI & " corresponde a " & rst(1)
'Cerramos conexiones y liberamos memoria
rst.Close
dbs.Close
Set rst = Nothing
Set dbs = Nothing
End Sub

17
Vistame en http://siliconproject.com.ar/neckkito/

Fijaos que:
- Indicamos que la bsqueda es indexada, a travs de
(rst.Index = "PrimaryKey")
La bsqueda utilizando Seek sigue la estructura
<rst.Seek comparador matemtico, valor a buscar (si hay
ms ndices definidos se colocan a continuacin, separados
por comas)>.
Hemos realizado una simplificacin a la hora de
mostrar la informacin. En lugar de utilizar nuestro
conocido rst.Fields(1).Value lo hemos simplificado a rst(1)

Con tan pocos datos no notamos diferencia, pero con muchos registros os aseguro que se nota
la velocidad del Seek.

AADIENDO UN REGISTRO
Hemos visto cmo modificar un registro. Ahora vamos a ver cmo aadimos un registro a una
tabla.

La adicin de un registro sigue la siguiente estructura

With rst
.AddNew
.Fields(x).Value = <NuevoValor>
.Update
End With

Vamos a crear una tabla, que llamaremos TAdiciones, que contendr dos campos:
[NomTrab] De tipo texto
[Sex] De tipo texto, tamao 1

Lo que haremos ser recorrer los registros de la tabla TTrabajadores y copiaremos el nombre
del trabajador en TAdiciones, junto con la inicial de su sexo.

El cdigo sera:

Private Sub cmdAdd_Click()


'Declaramos las variables
Dim dbs As DAO.Database
Dim rst As DAO.Recordset 'Recordset para TTrabajadores
Dim rstAdd As DAO.Recordset 'Recordset para TAdiciones
'Definimos la base de trabajo y abrimos los recordsets
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("TTrabajadores", dbOpenSnapshot)
Set rstAdd = dbs.OpenRecordset("TAdiciones", dbOpenTable)
'Nos situamos en el primer registro de TTrabajadores
rst.MoveFirst
'Iniciamos el recorrido de registros
Do Until rst.EOF
'Aadimos los datos del primer registro a la tabla TAdiciones
With rstAdd
.AddNew
.Fields("NomTrab").Value = rst.Fields("Nombre").Value

18
Vistame en http://siliconproject.com.ar/neckkito/
.Fields("Sex").Value = Left(rst.Fields("Sexo").Value, 1)
.Update
End With
'Nos movemos al registro siguiente
rst.MoveNext
Loop
'Abrimos la tabla para ver los resultados
DoCmd.OpenTable "TAdiciones", , acReadOnly
'Cerramos conexiones y liberamos memoria
rst.Close
rstAdd.Close
dbs.Close
Set rst = Nothing
Set rstAdd = Nothing
Set dbs = Nothing
End Sub

Como vemos, hemos utilizado un recordset dentro de otro recordset para ir aadiendo los
datos en funcin de los valores de origen, registro por registro.

Fijaos que rst lo hemos abierto en modo dbOpenSnapshot, porque slo nos interesaba mirar
los datos; en cambio, rstAdd lo hemos tenido que abrir en modo dbOpenTable, porque
necesitbamos modificar/aadir datos en la tabla.

UNOS PREPARATIVOS NECESARIOS


Los datos que tenemos en la BD son un poco simples, y quiz no se pueda apreciar bien el
potencial del cdigo. Adems, como vamos a ver un ejemplo un poco ms complicado vamos a
necesitar algunos datos ms para operar.

As pues vamos a hacer un alto en el camino y vamos a aumentar nuestra informacin dentro
de las BD's con las que vamos a operar.

1.- Vamos a aadir un campo a nuestra tabla TTrabajadores, de tipo texto, que llamaremos
[Dpto]. Aadimos unos cuantos trabajadores ms y les asignamos un departamento. Nos
moveremos con tres valores: Comercial / Administracin / Ventas.

Por ejemplo, los datos de mi tabla quedaran as:

2.- Vamos a aadir una tabla en nuestra BD de pruebas que nos va a recoger unos cuantos
trabajos realizados por nuestros trabajadores. A esa tabla la vamos a llamar TTrabajos. Tendr
la siguiente estructura:

19
Vistame en http://siliconproject.com.ar/neckkito/
Tened en cuenta que el campo [IdTrab]
est creado a travs del asistente,
buscando en la tabla TTrabajadores y
seleccionando los campos [DNI] y
[Nombre]. Evidentemente el valor que
nos guardar ser la clave principal,
esto es, el DNI del trabajador.

Rellenamos esta tabla con algunos


datos. Por ejemplo, yo la he rellenado
as:

3.- Creamos otra tabla, la tabla TRetribuciones, con la siguiente estructura:

4.- Vamos a crearnos otra base de datos (otro archivo de Access), al que vamos a llamar
Retribuciones.mdb (o .accdb. Recordad que debis mantener la extensin que le hayis puesto
cuando escribamos el cdigo). Nuestra BD de pruebas y esta otra BD estarn en el mismo
directorio.

4.- En esa nueva BD vamos a crear una tabla, que llamaremos TPrecioHora, que tendr la
siguiente estructura:

Rellenamos la tabla con los siguientes datos:

20
Vistame en http://siliconproject.com.ar/neckkito/
Bueno, bueno... ya tenemos la carne en el asador.
Sigamos.

EL EJEMPLO FINAL: UN MIX DE TODO LO APRENDIDO.


La idea del ejemplo es construir los datos de la tabla TRetribuciones a travs de cdigo, para
saber cunto dinero, por horas extras, les debemos pagar a nuestros empleados.

Vamos a necesitar, como SQL's:

Una consulta que nos sume las horas realizadas por cada trabajador.
Una consulta que nos indique el nombre del trabajador que estamos examinando en ese
momento y el departamento al que pertenece.

Estas dos consultas podran resumirse en un solo paso, pero yo lo har en dos para practicar el
tema de los recordset sobre SQL.

Qu pasa? Pues, por ahora, nuestros conocimientos de SQL son un poco limitados. Vamos a
hacer un poco de trampa y le diremos a Access que nos de una pista de cmo construir
nuestra SQL

Cmo sera nuestra SQL


Lo que haremos ser lo siguiente:

1.- Creamos una consulta en vista diseo sobre la tabla TTrabajos. Aadimos slo los campos
[IdTrab] y [Horas] y la convertimos en una consulta de totales. Agrupamos el campo [Horas]
por suma. Nos debera quedar una cosa as:

21
Vistame en http://siliconproject.com.ar/neckkito/
Ahora situamos esta consulta en vista SQL. Nos encontraremos con lo siguiente:

Pues ya sabemos cmo sera la SQL que nos da la suma de


las horas. Tomamos nota de este cdigo SQL para poderlo
utilizar en nuestro cdigo. A esta sql la llamaremos
sqlSumaHoras (en el cdigo). Ya podemos borrar esta
consulta.

ESTRUCTURACIN DEL CDIGO


Pensad, como os comentaba al principio del captulo, al ponerme filosfico sobre el recordset,
que a m me va bien ponerme en situacin e imaginarme cmo lo hara si lo tuviera que
hacer con lpiz y papel.

Es decir:

La SQL sqlSumaHoras nos proporciona dos datos: el identificador del trabajador y el nmero
de horas.

Para qu me sirve el identificador del trabajador? Pues realiza dos funciones:


Me da el DNI para buscar el nombre del trabajador
Me da el DNI para buscar el departamento al que pertenece el trabajador.

Y estos datos, dnde los tengo? En la tabla TTrabajadores.

Conclusin, puedo utilizar el DNI para otra SQL, sqlDatos, que me devuelva esos dos datos que
voy a necesitar.

Para qu me sirve el nmero de horas? Pues para multiplicar las horas por el precio hora.
Pero no hay un solo precio hora, sino que depende del departamento. Y de dnde saco el
departamento? Pues me lo va a dar sqlDatos, como comentbamos hace un momento, y si s
el departamento s el precio hora.

Bueno: ahora ya tengo el identificador del trabajador, su nombre, sus horas y su precio hora
segn el departamento. Qu hago con todos esos datos? Pues necesito escribirlos en la tabla
TRetribuciones.

Creo que, en principio, ya tenemos todos los pasos ms o menos claros para meterme con el
cdigo.

Vamos all

DESARROLLANDO EL CDIGO
Os voy a poner el cdigo extensamente comentado. Pensad que todo lo que vamos a hacer, de
una manera u otra, ya lo hemos visto en apartados anteriores. Slo nos falta la soltura para
combinarlo todo... y para eso estamos, para que cojis soltura.

22
Vistame en http://siliconproject.com.ar/neckkito/
En vez de asignaciones directas voy a pasar todos los valores por variables. Creo que de esta
manera lo veris ms claro.

El cdigo sera:


Private Sub cmdCalculoPagoHoras_Click()
'Declaramos las variables
Dim bdExt As String 'Nos definir la ruta, nombre y
extensin de Retribuciones.mdb
Dim sqlSumaHoras As String 'SQL que nos dar el total
de horas por trabajador
Dim sqlDatos As String 'SQL que nos dar los datos del nombre y departamento
Dim vDNI As Integer 'Variable que recoge el DNI del trabajador
Dim vNom As String 'Variable que recoge el nombre del trabajador
Dim vDep As String 'Variable que recoge el departamento del trabajador
Dim vPH As Currency 'Variable que recoge el Precio Hora
Dim vNH As Integer 'Variable que recoge el nmero de horas
Dim dbs As DAO.Database 'Ser nuestra base actual
Dim dbsRetrib As DAO.Database 'Ser nuestra base Retribuciones.mdb
Dim rstRetrib As DAO.Recordset 'Ser el recordset sobre la tabla TPrecioHora
Dim rstSumaHoras As DAO.Recordset 'Ser el recordset de sqlSumaHoras
Dim rstDatos As DAO.Recordset 'Ser el recordset de sqlDatos
Dim rst As DAO.Recordset 'Ser el recordset sobre la tabla TRetribuciones
'Definimos las dbs's
Set dbs = CurrentDb
bdExt = Application.CurrentProject.Path & "\Retribuciones.mdb"
Set dbsRetrib = DBEngine.OpenDatabase(bdExt)
'Creamos el recordset que nos debe rellenar la tabla TRetribuciones
Set rst = dbs.OpenRecordset("TRetribuciones", dbOpenTable)
'Creamos la SQL sqlSumaHoras (recordad que hemos copiado el cdigo de la consulta
'que hemos creado y que hemos puesto en vista SQL. NO PONEMOS EL PUNTO Y COMA
FINAL!
sqlSumaHoras = "SELECT TTrabajos.IdTrab, SUM(TTrabajos.Horas) AS SumaDeHoras"
sqlSumaHoras = sqlSumaHoras & " FROM TTrabajos GROUP BY TTrabajos.IdTrab"
'Creamos el recorset sobre la sql
Set rstSumaHoras = dbs.OpenRecordset(sqlSumaHoras, dbOpenSnapshot)
'Comprobamos que haya registros. Si no hay registros salimos
If rstSumaHoras.RecordCount = 0 Then Exit Sub
'Nos movemos al primer registro
rstSumaHoras.MoveFirst
'Iniciamos el recorrido de los registros
Do Until rstSumaHoras.EOF
'Cogemos el identificador del trabajador y el total de horas realizadas
vDNI = rstSumaHoras.Fields(0).Value
vNH = rstSumaHoras.Fields(1).Value
'Ya tenemos el DNI. Vamos a crear la consulta sqlDatos que nos d los datos
'que necesitamos, que son el nombre y el departamento. Crearemos la sql
'ya filtrada por DNI
sqlDatos = "SELECT TTrabajadores.Nombre, TTrabajadores.Dpto FROM TTrabajadores"
sqlDatos = sqlDatos & " WHERE TTrabajadores.DNI=" & vDNI
'Creamos el recordset sobre esta consulta
Set rstDatos = dbs.OpenRecordset(sqlDatos, dbOpenSnapshot)
'Cogemos los valores que necesitamos
vNom = rstDatos.Fields(0).Value
vDep = rstDatos.Fields(1).Value

23
Vistame en http://siliconproject.com.ar/neckkito/
'Ya sabemos el departamento. Vamos a buscar el precio hora de ese departamento,
'pero la bsqueda la realizaremos en la BD Retribuciones.mdb, en la tabla
'TPrecioHora. Para ello, recorreremos los registros de TPrecioHora hasta encontrar
'la coincidencia de departamentos
'Creamos el recordset
Set rstRetrib = dbsRetrib.OpenRecordset("TPrecioHora",
dbOpenSnapshot)
'Aqu podra haber un control de registros,
pero ya sabemos cmo hacerlo
'Nos situamos en el primer registro
rstRetrib.MoveFirst
'Iniciamos el recorrido de registros
Do Until rstRetrib.EOF
'Aplicamos el criterio a travs de un bloque IF...END IF
If rstRetrib.Fields("Departamento").Value = vDep Then
vPH = rstRetrib("Precio").Value
Exit Do 'Ya hemos encontrado lo que buscbamos. Podemos salir
End If
'Nos movemos al siguiente registro
rstRetrib.MoveNext
Loop
'Y ya tenemos todos los elementos que necesitbamos. Vamos a crear el registro
'de resultados en nuestra tabla TRetribuciones
With rst
.AddNew
.Fields("DNI").Value = vDNI
.Fields("Nombre").Value = vNom
.Fields("ACobrar").Value = vNH * vPH
.Update
End With
'Listo para un registro de sqlSumaHoras. Vamos a analizar el siguiente
rstSumaHoras.MoveNext
Loop
'Mostramos los resultados
DoCmd.OpenTable "TRetribuciones", , acReadOnly
'Cerramos conexiones y liberamos memoria
rstRetrib.Close
rstSumaHoras.Close
rstDatos.Close
rst.Close
dbs.Close
dbsRetrib.Close
Set rstRetrib = Nothing
Set rstSumaHoras = Nothing
Set rstDatos = Nothing
Set rst = Nothing
Set dbs = Nothing
Set dbsRetrib = Nothing
End Sub

Ahora tendra que decir lo de Fcil, verdad?, pero creo que, para este ejemplo, no os lo
dir... je, je... Lo cambiar por

nimo!

24
Vistame en http://siliconproject.com.ar/neckkito/
UNAS PALABRAS FINALES
Hasta aqu el sistema DAO. Nos queda pendiente la
coleccin ERROR, pero lo veremos como algo independiente
en un captulo prximo. Creo que este captulo ha sido
bastante intenso y dejaremos descansar nuestros pobres
cerebros.

En el siguiente captulo ya nos meteremos con ADO.

25
Vistame en http://siliconproject.com.ar/neckkito/

Potrebbero piacerti anche