You are on page 1of 11

AGENDA AVISADORA1

A travs de este ejemplo veremos cmo Access puede


convertirse en una agenda de tareas que nos avise de la
proximidad de una tarea a su vencimiento en funcin del
periodo de preaviso que le hayamos establecido.
En principio la mecnica de funcionamiento sera la
siguiente: introducimos las tareas en la BD, asignndoles
un vencimiento y un periodo de preaviso. Abrimos la BD (en
otro momento) y Access nos avisar de que hay tareas que
estn ya vencidas (si las hay), mostrndonos una lista de
dichas tareas. Adems podremos ver tres tipologas de
tareas ms: las tareas atrasadas, las tareas sin vencimiento
y las tareas completadas. Finalmente podremos seleccionar
un da y ver qu tareas deben realizarse en ese da en
concreto.
La gracia del ejemplo, adems del aviso en s, es que slo vamos a utilizar dos formularios
para todo esto... tachn!
Como ya tenemos una idea clara (espero) de lo que nos har la BD sin ms pongmonos
manos a la obra.

CREANDO NUESTRAS TABLAS


Vamos a crearnos una tabla, que llamaremos TEventos, que tendr la siguiente estructura:

El campo [FechEvento] tiene, como valor predeterminado, la siguiente expresin


Fecha()
El campo [LapsoPreaviso], aunque ser modificable por el usuario, lo he establecido en quince
das de preaviso. Evidentemente nosotros podemos establecer, por defecto, el tiempo que
queramos simplemente indicando otro valor predeterminado.

CREANDO NUESTROS FORMULARIOS DE INICIO Y DE MEN


Vamos a crearnos un formulario en blanco que guardaremos con el nombre de FMenu. Este
1

La BD de ejemplo os la podis bajar aqu

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

formulario nos har de panel de control para que el usuario tenga acceso a todas las
opciones de la aplicacin.
Por ahora dejamos el formulario as creado. Volveremos a l
un poco ms tarde.
Ahora nos creamos otro formulario en blanco, que
guardaremos como FInicio. No hace falta que hagamos, por
ahora, ninguna operacin con el formulario. Simplemente
tened en cuenta que debemos configurar Access para que,
al abrirse, nos cargue este formulario (si no sabemos cmo
se hace esto podis echar un vistazo a este artculo).

CREANDO NUESTRO MOLDE DE FORMULARIO Y, A


CONTINUACIN, NUESTRO FORMULARIO
Vamos a construir una consulta que nos va a hacer de molde para un formulario. Esta
consulta, a pesar de que la guardaremos ahora, con posterioridad la vamos a eliminar (si
queremos, claro).
La consulta es tan simple como lo siguiente:

La podemos guardar por el nombre por defecto, esto es, Consulta1.


Vamos a crearnos un formulario sobre esta consulta, que guardaremos como FInfo, pero, ojo,
lo haremos en forma de formularios continuos (varios elementos).
Vamos, en el encabezado del formulario, a insertar un botn de comando, que llamaremos
cmdCerrar2.
En el evento Al hacer click de dicho botn vamos a generar el siguiente cdigo 3:

2
3

Para asignar un nombre a un control lo que debemos hacer es sacar las propiedades de ese control e irnos a la Pestaa Otras
Nombre. Ah escribimos el nombre que queramos.
Para generar cdigo debemos sacar las propiedades del control Pestaa Eventos, y nos situamos en la parte blanca a la
derecha del evento que queremos programar. Veremos un pequeo botn de puntos suspensivos. Si hacemos click sobre l nos
aparecer una ventana que nos pedir qu operacin deseamos realizar. Le indicamos que queremos generar cdigo.

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


Private Sub cmdCerrar_Click()
'Cerramos el formulario actual
DoCmd.Close acForm, Me.Name
'Abrimos FMenu
DoCmd.OpenForm "FMenu"
End Sub

Por ejemplo, a m me ha quedado as:

Con esto, si queremos, ya podemos borrar nuestra Consulta1 (si queremos).


Ahora vamos a generar unos cdigos que nos permitirn controlar las posibles acciones
errneas del usuario. Estos cdigos despus los vamos a reutilizar en el formulario que nos
permitir dar de alta los eventos, por lo que no os asustis al ver tanto cdigo, pues van a
ser prcticamente los mismos.
En primer lugar vamos a controlar la fecha de vencimiento. Para ello seleccionamos el campo
[FechVto] y le generamos, en el evento despus de actualizar, el siguiente cdigo:

Private Sub FechVto_AfterUpdate()


'Declaramos las variables
Dim vFAhora As Date, vFV As Variant
Dim vLap As Long
'Cogemos el valor de la fecha actual
vFAhora = Date
'Cogemos el valor de la fecha de vencimiento
vFV = Me.FechVto.Value
'Cogemos el valor del lapso de preaviso
vLap = Me.LapsoPreaviso.Value
'Si [FechVto] est vaca avisamos y obligamos a su rellenado
If IsNull(vFV) Then
MsgBox "La fecha de vencimiento no puede quedar en blanco", vbExclamation, "ERROR"
Me.LapsoPreaviso.SetFocus
Me.FechVto.SetFocus
Exit Sub
End If
'Si [FechVto] es menor que la fecha actual avisamos y borramos el valor introducido
If vFAhora > vFV Then
MsgBox "El vencimiento no puede ser anterior a la fecha actual", vbExclamation, "ERROR"
Me.FechVto.Value = Null
Me.LapsoPreaviso.SetFocus
Me.FechVto.SetFocus
Exit Sub
End If
'Si [FechVto] es inferior a 15 das respecto de [FechEvento] situamos el lapso de preaviso en cero das
If vFV - vFAhora < vLap Then
MsgBox "El vencimiento es inferior a " & vLap & " das. El tiempo de preaviso se establecer en cero das", _
vbExclamation, "AVISO"
Me.LapsoPreaviso.Value = 0
End If

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

Me.LapsoPreaviso.SetFocus
End Sub

En segundo lugar vamos a controlar que el lapso de


preaviso sea correcto. Para ello seleccionamos el campo
[LapsoPreaviso] y en el evento Despus de actualizar
generamos el siguiente cdigo:

Private Sub LapsoPreaviso_AfterUpdate()


'Declaramos las variables
Dim vLap As Variant
Dim vFAhora As Date, vFV As Date
'Cogemos la fecha actual
vFAhora = Date
'Cogemos el valor del lapso
vLap = Me.LapsoPreaviso.Value
'Cogemos la fecha de vencimiento
vFV = Me.FechVto.Value
'Si el preaviso est vaco volvemos a asignar cero das
If IsNull(vLap) Then Me.LapsoPreaviso.Value = 0
'Si establecemos un preaviso imposible avisamos y situamos el preaviso en cero das
If vFV - vFAhora < vLap Then
MsgBox "El lapso de preaviso no puede ser de " & vLap & " das. Por favor, revselo", _
vbInformation, "AVISO"
Me.LapsoPreaviso.Value = 0
Exit Sub
End If
End Sub

Finalmente vamos a controlar si la tarea es indefinida o no. Para ello sacamos las propiedades
del campo [Indefinida] y en el evento Despus de actualizar le generamos el siguiente
cdigo:

Private Sub Indefinida_AfterUpdate()


'Declaramos las variables
Dim vIndef As Boolean
Dim resp As Integer
'Miramos si se ha marcado el check
vIndef = Me.Indefinida.Value
'Si se ha marcado avisamos que fecha vencimiento, si la hay, se borrar y pedimos confirmacin
If vIndef = True Then
If Not IsNull(Me.FechVto.Value) Then
resp = MsgBox("Si la tarea es indefinida se eliminar la fecha de vencimiento. Correcto?", _
vbQuestion + vbYesNo, "CONFIRMACIN")
If resp = vbNo Then 'Si la respuesta es no
Me.Indefinida.Value = False 'Restituimos el valor del check
Else 'Si la respuesta es s
Me.FechVto.Value = Null
End If
End If
Else 'Si lo que se hace es desmarcar el check
If IsNull(Me.FechVto.Value) Then 'Si no hay fecha de vencimiento recordamos que debe haberla
MsgBox "Recuerde que debe indicar una fecha de vencimiento", vbInformation, "AVISO"
Me.FechVto.SetFocus
End If
End If
End Sub

Y listo. No os preocupis ahora por el tema de pero si no existe la consulta que da origen a
4

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

los datos! (porque, en teora, la hemos borrado). Eso lo arreglaremos un poco ms adelante.

CREANDO NUESTRO FORMULARIO


FTAREAS
Para dar de alta las nuevas tareas vamos a crearnos un
formulario normal basado en la tabla TEventos. Una vez
creado realizaremos las siguientes manipulaciones:
1.- Eliminamos el campo [Id]
2.- Sacamos las propiedades del campo [FechEvento] y nos vamos a Pestaa Datos
Habilitado y situamos su propiedad en NO.
Este campo simplemente nos recoger la fecha en que hemos dado de alta la tarea.
3.- En el evento Despus de actualizar del campo [FechVto] le creamos el mismo cdigo que
hemos creado en FInfo para el mismo campo (el procedimiento < Private Sub
FechVto_AfterUpdate()>)
4.- En el evento Despus de actualizar del campo [LapsoPreaviso] le creamos el mismo
cdigo que hemos creado en FInfo para ese campo (el procedimiento < Private Sub
LapsoPreaviso_AfterUpdate()>)
5.- En el evento Despus de actualizar del campo [Indefinida] le creamos el mismo cdigo
que hemos creado en FInfo para el campo del mismo nombre (el procedimiento < Private Sub
Indefinida_AfterUpdate()>)
6.- En la cabecera del formulario insertaremos un botn de comando, que llamaremos
cmdCerrar, que tendr el siguiente cdigo en el evento Al hacer click:

Private Sub cmdCerrar_Click()


DoCmd.Close acForm, Me.Name
DoCmd.OpenForm "FMenu"
End Sub

Y asunto finiquitado.

CONFIGURANDO NUESTRO FORMULARIO FINICIO, QUE


HAR ALGO MS QUE DARNOS LA BIENVENIDA
Nuestro formulario de inicio va a realizar una operacin secreta de la que el usuario no se va
a dar cuenta, pero que va a aportarnos una informacin importante: si hay o no tareas con
lapso de preaviso.
Por ejemplo, yo he hecho una cosa as:

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

Para ello vamos a situar FInicio en vista diseo, sacaremos las propiedades del formulario y
nos vamos a Pestaa Otras, y situamos en S las propiedades Emergente y Modal
Ahora nos vamos a Pestaa Eventos Intervalo de cronmetro, y le escribimos ah el valor
2000.
Tened en cuenta que 1000 = 1 segundo; lgicamente, 2000
demasiado tiempo lo podemos bajar, o si es demasiado poco y
segundos, pues escribiramos 6000 (eso se hara eterno!). Slo
lapso es muy corto no os va a dar tiempo a cortar el cdigo,
molesto... je, je...

son dos segundos. Si es


queremos, por ejemplo, 6
tened en cuenta que si el
y eso puede ser bastante

En esa misma pestaa nos vamos al evento Al cronmetro y le generamos el siguiente


cdigo:

Private Sub Form_Timer()


Call origenFInfo(Me.Name, 1, True)
End Sub

Qu hace este cdigo? Pues como vamos a emplear un slo formulario tambin vamos a
economizar en cdigo. Veremos cmo nos construiremos, a continuacin, un mdulo con un
procedimiento llamado origenFInfo, donde, como argumentos, le pasaremos el nombre del
formulario (Me.Name) y un identificador propio (es decir, que nos hemos inventado nosotros
mismos), que nos indicar el tipo de consulta que queremos hacer.
En este caso, el 1 ser la consulta referida a las tareas ya vencidas o que ya nos caen dentro
del lapso de preaviso.
Como vamos a necesitar saber si el cdigo es llamado desde FInicio o desde FMenu le pasamos
el tercer argumento (que veremos que es opcional en el mdulo), dicindole que es true, lo
que implica que el cdigo es llamado desde FInicio.

CREANDO NUESTRO MDULO


Vamos a crearnos un mdulo para que nos haga todo el trabajo de construccin de
consultas, en funcin de los parmetros que le pasemos.
El cdigo que vamos a generar a continuacin requiere el registro de la librera Microsoft DAO

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

3.6 Object Library (o mdulo equivalente), si no la tuviramos registrada 4.


Veamos cmo construimos el cdigo (que est comentado) y despus haremos algunos
comentarios:

Public Sub origenFInfo(elForm As String, numConsulta As Byte, _


Optional esFInicio As Boolean = False, Optional ByVal laFecha As Date)
'Neckkito --- 16/02/13
'Requiere registro de la librera "Microsoft DAO 3.6 Object Library" o
'mdulo equivalente
'Declaramos las variables
Dim vLimite As Variant
Dim miSql As String
Dim resp As Integer
Dim rst As DAO.Recordset
'Creamos el inicio de la consulta
miSql = "SELECT TEventos.FechVto, TEventos.LapsoPreaviso," _
& " TEventos.Indefinida, TEventos.Completada,"
Select Case numConsulta
Case 1
'Acabamos de construir la SQL con las tareas no completadas
'y sobre las que ya se haya entrado en periodo de preaviso.
miSql = miSql _
& " TEventos.Obs, [FechVto]-[LapsoPreaviso] AS FLimite FROM TEventos" _
& " WHERE TEventos.Completada=FALSE AND" _
& " ([FechVto]-[LapsoPreaviso])<=Date()"
Case 2
'Acabamos de construir la SQL con las tareas no completadas
'y sin vencimiento
miSql = miSql _
& " TEventos.Obs FROM TEventos WHERE TEventos.Completada=FALSE AND" _
& " TEventos.Indefinida=TRUE"
Case 3
'Acabamos de construir la SQL con las tareas completadas
miSql = miSql _
& " TEventos.Obs FROM TEventos WHERE TEventos.Completada=TRUE"
Case 4
'Acabamos de construir la SQL para las tareas del da seleccionado
'que no estn finalizadas
miSql = miSql _
& " TEventos.Obs FROM TEventos WHERE TEventos.Completada=FALSE AND" _
& " TEventos.FechVto=#" & Format(laFecha, "mm/dd/yy") & "#"
End Select
'Creamos el recorset sobre la SQL
Set rst = CurrentDb.OpenRecordset(miSql)
If esFInicio = True Then 'Si la llamada viene de FInicio...
'Si la SQL no devuelve registros
If rst.RecordCount = 0 Then
'Cerramos el formulario actual y abrimos FMenu
DoCmd.Close acForm, elForm
DoCmd.OpenForm "FMenu"
GoTo Salida
'Si hay registros pedimos al usuario si quiere ver esos registros o no
Else
resp = MsgBox("Hay tareas vencidas o con periodo de preaviso cumplido. Desea verlas?", _
vbQuestion + vbYesNo, "ATENCIN!")
If resp = vbNo Then 'Si no quiere verlos cerramos el formulario actual y abrimos FMenu
4

Para registrar una referencia debemos irnos, en el editor de VB, a Men Herramientas Referencias... Se nos abrir una
ventana mostrndonos todas las referencias disponibles. Buscamos la que nos interese, marcamos su check y aceptamos.

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

DoCmd.Close acForm, elForm


DoCmd.OpenForm "FMenu"
GoTo Salida
End If
End If
End If
'Abrimos FInfo en vista diseo y oculto
DoCmd.OpenForm "FInfo", acDesign, , , , acHidden
'Le indicamos que su origen de datos es nuestra SQL
Forms!FInfo.RecordSource = miSql
'Cerramos FInfo guardando los cambios
DoCmd.Close acForm, "FInfo", acSaveYes
'Cerramos el formulario actual
DoCmd.Close acForm, elForm
'Abrimos FInfo para ver la informacin y editarla
DoCmd.OpenForm "FInfo", , , , acFormEdit
Forms!FInfo.AllowAdditions = False
Salida:
'Cerramos conexiones y liberamos memoria
rst.Close
Set rst = Nothing
End Sub

Qu hace nuestro cdigo? A grandes rasgos lo que hace es lo siguiente:


1.- Crea el inicio comn de la SQL que va a ser el origen de FInfo.
2.- Qu consulta queremos? Para responder a esta pregunta el cdigo busca qu parmetro le
hemos pasado a travs de numConsulta
3.- En funcin de numConsulta, y a travs del SELECT CASE, acabamos de construir la SQL
de la consulta, aplicando los filtros oportunos.
4.- Antes hemos analizado si el cdigo es llamado desde FInicio o desde otro formulario (a
travs del parmetro esFInicio), porque en este caso debemos, en primer lugar, informar al
usuario de que hay tareas vencidas y, en segundo lugar, pedirle si quiere verlas o no.
5.- Para poder cambiar el origen del formulario necesitamos situar FInfo en vista diseo, ya
que es la nica vista que permite manipular el origen del formulario. Entonces el cdigo lo que
hace es abrir FInfo en vista diseo, pero oculto (para que el usuario no se percate de que se
est manipulando el formulario), le cambia el origen del formulario en funcin de la SQL
creada, cierra FInfo, guardando los cambios, y, ahora s, ya puede abrir FInfo en vista
Formulario para mostrar la informacin solicitada.

PROGRAMANDO NUESTRO FMENU


Ya casi tenemos terminada la aplicacin. Vamos a situar nuestro FMenu en vista diseo y
vamos a:
1.- Aadir un botn de comando, que llamaremos cmdAbreFTareas, que tendr este cdigo:

Private Sub cmdAbreFTareas_Click()


DoCmd.Close acForm, Me.Name
DoCmd.OpenForm "FTareas", , , , acFormAdd
End Sub

El argumento acFormAdd nos permite dejar el formulario preparado para la introduccin de un


nuevo registro.
2.- Aadir un botn de comando, que llamaremos cmdCVencidas, que tendr el siguiente
cdigo:

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


Private Sub cmdCVencidas_Click()
Call origenFInfo(Me.Name, 1)
End Sub

Fijaos que en la llamada a origenFInfo() slo le pasamos los


argumentos obligatorios, que son el nombre del formulario
en el que estamos y 1, que nos define el tipo de consulta
que queremos.
3.Aadir
un
botn
de
comando,
cmdCIndefinidas, con el siguiente cdigo:

que

llamaremos

Private Sub cmdCIndefinidas_Click()


Call origenFInfo(Me.Name, 2)
End Sub

Ahora el segundo argumento es 2 porque queremos que se ejecute la SQL del CASE 2, que
es la que nos da las tareas no completadas e indefinidas.
4.- Aadir un botn de comando, que llamaremos cmdCCompletadas, con el siguiente cdigo:

Private Sub cmdCCompletadas_Click()


Call origenFInfo(Me.Name, 3)
End Sub

Ahora creo que ya entendis porque pasamos como ltimo argumento el 3, verdad?
5.- Aadimos un cuadro de texto, al que pondremos de nombre txtFecha. Sacamos sus
propiedades y nos vamos a la pestaa Formato Formato, y le establecemos un formato de
fecha corta.
De esta manera ser el propio Access quien nos controle si el valor introducido es vlido o no.
Ahora, para ese textbox, en su evento Despus de actualizar, generamos el cdigo:

Private Sub txtFecha_AfterUpdate()


'Declaramos las variables
Dim laFecha As Variant
'Cogemos la fecha introducida
laFecha = Me.txtFecha.Value
'Si no hay valor salimos
If IsNull(laFecha) Then Exit Sub
'Convertimos la fecha en dato tipo fecha para evitarnos errores de tipo
'al llamar al procedimiento origenFInfo
laFecha = CDate(laFecha)
'Llamamos al procedimiento
Call origenFInfo(Me.Name, 4, , laFecha)
End Sub

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


Fijaos que, al tener un elemento ms, que es la fecha que
nos va a hacer de filtro, la llamada a la funcin utiliza los
dos parmetros obligatorios, debemos indicar que el primer
parmetros opcional no lo indicamos (de ah el espacio
entre comas), y que el segundo parmetros opcional s lo
pasamos, y que viene representado por el valor recogido en
la variable laFecha.
Y con esto podemos dar por finalizado la programacin de
nuestra aplicacin.

UNOS COMENTARIOS
Qu pasara si quisiera aadir ms campos a FInfo? Si hemos entendido la mecnica de
funcionamiento de la aplicacin no deberamos tener muchos problemas para poder conseguir
nuestro propsito. Sin embargo, para clarificar ideas, os indico lo que deberamos hacer, en
general:
1.- Aadir ese nuevo campo a nuestra consulta molde, si an no tenemos creado FInfo
2.- Si ya tenemos creado FInfo, aadirle el nuevo campo a travs de la opcin Campos
Disponibles (para Access 2003 habra que sacar la tabla origen del formulario a travs del
botn correspondiente de la barra de botones).
3.- En el cdigo del mdulo deberamos aadir ese nuevo campo en la SQL, en la parte del
cdigo donde se indica que creamos el inicio de la consulta.
Por ejemplo, si creramos un campo llamado [Importante], en el cdigo escribiramos, por
ejemplo:

'Creamos el inicio de la consulta


miSql = "SELECT TEventos.FechVto, TEventos.LapsoPreaviso," _
& " TEventos.Indefinida, TEventos.Completada, TEventos.Importante,"

Es muy importante que la SQL finalice con esa coma al final. Ojo!
Qu pasara si quisiramos aadir una nueva consulta utilizando el nuevo campo? Pues el
proceso sera:
1.- Como es una nueva consulta debemos asignarle un identificador de consulta. Como
tenemos hasta el 4 el nuevo sera el 5.
2.- Creamos un nuevo CASE en el cdigo del mdulo aadiendo el resto de la SQL de la
consulta. Evidentemente siempre antes del END SELECT.
3.- En el botn que nos llama a la nueva consulta pasarle correctamente los argumentos
obligatorios.
Por ejemplo, si queremos filtrar por ese nuevo campo [Importante], y que las tareas no estn
completadas, aadiramos el siguiente CASE:

Case 5
'Acabamos de construir la SQL con las tareas no completadas
'e importantes

10

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

miSql = miSql _
& " TEventos.Obs FROM TEventos WHERE TEventos.Completada=FALSE AND" _
& " Teventos.Importante=TRUE"
Y la llamada del botn de comando sera:

Call origenFInfo(Me.Name, 5)

Lo dicho: entendida la mecnica nos resultar muy fcil


introducir nuevos elementos.

PARA FINALIZAR
Ahora s... Ya tenemos nuestra agenda de tareas, que adems nos avisa de vencimientos con
preavisos, y todo ello economizando recursos utilizando un slo formulario para recoger
todas las consultas que podamos hacer.
Espero que este ejemplo os pueda ser til. Un saludo, y...
suerte!

11

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

You might also like