Vous êtes sur la page 1sur 24

CURSO DE VB

CAPTULO 71

ndice de contenido
APLICANDO FILTROS......................................................................................................................2
UNAS PALABRAS INICIALES....................................................................................................2
LA PREPARACIN DEL EJEMPLO DE ESTE CAPTULO.......................................................2
EL PRIMER FILTRO......................................................................................................................2
LA FUNCIN NZ......................................................................................................................4
SEGUIMOS CON NUESTRO FILTRO.....................................................................................5
FILTRO POR CONSULTA.............................................................................................................6
FILTROS COMPUESTOS..............................................................................................................7
INCISO: ESE COMBO CON VALORES REPETIDOS............................................................8
SIGAMOS...................................................................................................................................8
FILTRO PARAMETRIZADO.........................................................................................................9
UN POCO MS SOBRE FILTROS COMPUESTOS..................................................................11
FILTRO EN EL PROPIO FORMULARIO...................................................................................13
A TRAVS DE UN FILTERON...........................................................................................13
UTILIZACIN DEL LIKE..............................................................................................14
A TRAVS DE UN CLON DEL RECORDSET DEL FORMULARIO...............................15
NUESTRO CLON NO ENCUENTRA EL VALOR............................................................16
MS ALL DE LOS FILTROS: CONTROLES Y LA PROPIEDAD ROWSOURCE...............16
TIPOS DE ROWSOURCE.......................................................................................................17
DATOS LISTA DE VALORES.........................................................................................17
DATOS TABLA/CONSULTA..........................................................................................18
MODIFICAR EL ORIGEN SI EL TIPO DE DATOS ES DE TABLA O CONSULTA...20
DATOS LISTA DE CAMPOS..........................................................................................21
LOS INFORMES Y LA PROPIEDAD RECORDSOURCE........................................................22
LO MISMO, PERO CON UN FORMULARIO.......................................................................23
UNAS PALABRAS FINALES......................................................................................................24

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

1
Vistame en http://siliconproject.com.ar/neckkito/
APLICANDO FILTROS

UNAS PALABRAS INICIALES


La idea principal de este captulo es proporcionaros
diferentes herramientas para realizar un filtro en formulario.
Veremos desde filtros simples hasta filtros ms complejos;
filtros en distintos formularios y filtros en el propio
formulario.

Como ya os he avanzado, la idea es proporcionaros ideas de cmo podemos realizar filtros,


habr algunos incisos donde veremos cmo construir un filtro para obtener los datos que
queremos que no sern estrictamente programacin pura y dura en VBA.

Y, como la construccin de estructuras de filtro es muy parecida a la construccin de


rowsources y de recordsources, aprovecharemos para echar un vistazo a estas dos
propiedades.

Y despus... a aplicar el que ms os guste!

LA PREPARACIN DEL EJEMPLO DE ESTE CAPTULO


Vamos a reciclar un poco la BD que desarrollamos en el captulo anterior. Por ello, partir de la
base (nunca mejor dicho) que tenemos delante esa aplicacin.

En este captulo veremos diversas maneras de crear un filtro, y lo complicaremos un poco para
ver cmo podemos combinar varios elementos que nos hagan de filtro.

Para practicar con diversas opciones modificaremos ligeramente nuestras tablas. Lo que
haremos ser:

1.- Copiar-pegar (estructura y datos) nuestra tabla TClientes, guardndola como TClientes2. A
esta ltima tabla le aadiremos dos campos ms, que sern:
[Edad] Numrico
[FechaAlta] Fecha/Hora

Directamente, sobre la tabla, aadiremos algunos registros, para poder desarrollar


prcticamente lo que veamos en los siguientes epgrafes.

2.- Creamos un nuevo formulario, que llamaremos FClientes2, basado sobre la tabla
TClientes2.

3.- Creamos un informe, basado en la tabla TClientes2, al que llamaremos RClientes2.

Algunos de los ejemplos los podremos aplicar tanto a formularios como informes.

As pues, manos a la obra.

EL PRIMER FILTRO
En nuestro formulario FMenu vamos a insertar un cuadro combinado. Cuando nos salga el
asistente lo configuraremos de la siguiente manera:

2
Vistame en http://siliconproject.com.ar/neckkito/
Buscamos los valores en una tabla
Elegimos la tabla TClientes2
Aadimos los campos [IdCli] y [NomCli]
Ordenamos, por ejemplo, ascendente sobre [NomCli]
Ocultamos la clave principal
Le ponemos como nombre de etiqueta Buscar
cliente

Ya tenemos pues configurado nuestro combo que nos


permitir visionar la ficha del cliente. Slo nos queda
identificarlo. Sacamos sus propiedades y en la pestaa
Otras Nombre escribimos cboBuscaCliente.

Hagamos un momento de receso: si examinamos las propiedades de ese combo, en la pestaa


Formato Nmero de columnas, veremos que aparece el valor 2. Efectivamente, hay dos
columnas, [IdCli] y [NomCli]. No vemos la primera porque hemos dicho, en el asistente, que
queramos ocultar la clave principal. Si ahora cambiamos de opinin y s queremos verla lo que
deberamos modificar es la propiedad Ancho de columnas. Donde nos pone 0 cm podramos
ponerle, por ejemplo, 1 cm (nos quedara: 1cm;2,54cm)

Si ahora nos vamos a la pestaa Datos Columna dependiente veremos que el valor que
aparece ah es 1. Eso nos est indicando que el valor que guarda el combo, tras haber
seleccionado un cliente, es el identificador del cliente. Nosotros no vamos a cambiar ese valor,
pero tened en cuenta que si quisiramos que lo que guardara fuera el nombre del cliente
deberamos cambiar ese valor a 2 (valor de la segunda columna).

Dicho lo anterior vamos a ver cmo filtrar nuestro formulario FClientes2 tras seleccionar un
cliente. Para ello, creamos un botn de comando (cmdBuscarCli) y en el evento Al hacer click
generamos el siguiente cdigo:

Private Sub cmdBuscarCli_Click()


Dim vCli As Integer
vCli = Nz(Me.cboBuscaCliente.Value, 0)
If vCli = 0 Then Exit Sub
DoCmd.OpenForm "FClientes2", , , "[IdCli]=" & vCli
DoCmd.Close acForm, Me.Name
End Sub

Si, en lugar de querer abrir el formulario, quisiramos abrir un informe filtrado, la mecnica es
prcticamente la misma. Suponiendo que tuviramos un botn de comando llamado
cmdInformeFiltrado el cdigo que deberamos asignar a ese botn sera:

Private Sub cmdInformeFiltrado_Click()


Dim vCli As Integer
vCli = Nz(Me.cboBuscaCliente.Value, 0)
If vCli = 0 Then Exit Sub
DoCmd.OpenReport "RClientes2", acViewPreview, , "[IdCli]=" & vCli
End Sub

3
Vistame en http://siliconproject.com.ar/neckkito/
LA FUNCIN NZ

Vemos que en el cdigo anterior hemos utilizado una nueva


funcin, que es Nz. La estructura de esta funcin es:

Nz (Valor, valor_si_nulo)

Si recordamos cuando hablbamos de definir el tipo de


variable comentbamos que es importante determinar qu
tipo de variable va a se la variable que vamos a utilizar.
En este caso puede darse el caso de que tras elegir un valor en el combo nos arrepintamos y
no seleccionemos ningn valor en el combo. En este caso el valor devuelto por el combo ser
NULL.

Si, para cubrirnos las espaldas, definimos la variable como Variant, no estaremos optimizando
recursos, pues Access (y lo digo de esta manera para entendernos) deber realizar tres
operaciones:
Una: saber que existe una variable, pero sin saber de qu tipo exactamente es
Dos: una vez sabe el tipo, cargar las caractersticas inherentes a este tipo de variable.
Tres: si la variable cambia de tipo, cargar de nuevo las caractersticas del nuevo tipo

La programacin inicial, si hubiramos seguido este criterio, debera haber sido la siguiente:

Private Sub cmdBuscarCli_Click()


Dim vCli As Variant
vCli = Me.cboBuscaCliente.Value
If IsNull(vCli) Then Exit Sub
DoCmd.OpenForm "FClientes2", , , "[IdCli]=" & vCli
DoCmd.Close acForm, Me.Name
End Sub

Aunque a veces no queda otro remedio que utilizar esta estructura, y por tema de optimizacin
de recursos que comentbamos, es mejor ya decir qu tipo de variable va a ser. Y cmo
soslayamos este problema? Pues a travs de la funcin NZ.

Lo que dice esta funcin es: devulveme el valor del combo (Me.cboBuscaCliente.Value).
Pero, si su valor es NULL, me devuelves un cero. Y por ello hemos escrito:

vCli = Nz(Me.cboBuscaCliente.Value, 0)

Como podemos ver, si obtenemos un NULL, nos devuelve un Integer, que en este caso es cero.
Debemos ir con cuidado con esto. Por ejemplo, si definimos la variable vCli como String en
caso de obtener un valor NULL debera devolvernos un valor tambin String. Por ejemplo, una
cadena vaca. As, en este supuesto, lo que deberamos haber escrito sera:

Dim vCli As String


vCli = Nz(Me.cboBuscaCliente.Value, )
If vCli = Then...

Moraleja: el valor que debe devolver NZ en caso de nulo debe ser del mismo tipo con el que
hemos definido la variable.

4
Vistame en http://siliconproject.com.ar/neckkito/
SEGUIMOS CON NUESTRO FILTRO
Ok. Vemos que nuestro filtro funciona perfectamente (o
debera!). Imaginemos que por el motivo que sea no
queremos que el valor escogido sea el identificador del
cliente, sino su nombre.

Una opcin podra ser:


Copiar-pegar el combo que hemos creado
Propiedades Pestaa Datos Columna
dependiente: 2

Es decir, le cambiamos la columna que guarda el valor. Si le decimos que es la 2 le estamos


indicando que guarde el nombre, y no el identificador.

Sin embargo, nosotros vamos a utilizar otra opcin, que es reutilizar nuestro combo sin tocar
sus propiedades. Para ello:

Creamos otro botn de comando, y lo llamamos cmdBuscarCli2


Al evento Al hacer click le generamos el siguiente cdigo:

Private Sub cmdBuscarCli2_Click()


Dim vCli As String
vCli = Nz(Me.cboBuscaCliente.Column(1), "")
If vCli = "" Then Exit Sub
DoCmd.OpenForm "FClientes2", , , "[NomCli]='" & vCli & "'"
DoCmd.Close acForm, Me.Name
End Sub

Vamos a ver qu ha pasado aqu:

La variable vCli ahora nos recoge el valor de la columna 1. Extraados? Pues debis
tener en cuenta que, cuando hacemos referencia, en VBA, a las columnas de un combo, la
numeracin empieza por cero. Es decir, que si lo plasmamos en una especie de esquema
obtendramos que:

Campo del combo Nmero columna Access Nmero columna VBA


[Id] Columna 1 Column(0)
[NomCli] Columna 2 Column(1)

Como ahora recogemos el nombre del cliente, nuestro vCli ha de ser de tipo String
Como es de tipo String, la funcin NZ debe devolver un String en caso de que el valor
sea vaco. Recordad lo visto en el epgrafe donde explicbamos esta funcin.
El filtro en la lnea del DoCmd.OpenForm debe ir entre comillas simples por ser,
precisamente, un String.

Y para esos hombres de poca fe que no lo ven claro, si queremos constatar sin ningn
gnero de dudas qu valor est cogiendo la variable vCli podemos modificar ligeramente
nuestros cdigos, aadiendo una sola lnea, para que el propio Access nos lo diga. As,
tendremos que:

.- Para nuestro cmdBuscarCli:


5
Vistame en http://siliconproject.com.ar/neckkito/
Private Sub cmdBuscarCli_Click()
Dim vCli As Integer
vCli = Nz(Me.cboBuscaCliente.Value, 0)
If vCli = 0 Then Exit Sub
DoCmd.OpenForm "FClientes2", , , "[IdCli]=" & vCli
DoCmd.Close acForm, Me.Name
MsgBox "Se ha encontrado el cliente: " & vCli
End Sub

.- Y para nuestro cmdBuscarCli2:

Private Sub cmdBuscarCli2_Click()


Dim vCli As String
vCli = Nz(Me.cboBuscaCliente.Column(1), "")
If vCli = "" Then Exit Sub
DoCmd.OpenForm "FClientes2", , , "[NomCli]='" & vCli & "'"
DoCmd.Close acForm, Me.Name
MsgBox "Se ha encontrado el cliente: " & vCli
End Sub

FILTRO POR CONSULTA


Como habamos comentado al principio del captulo sobre el tema de explicaros varias
sistemticas sobre cmo conseguir un filtro, vamos a ver cmo podemos hacer lo mismo que
hemos visto hasta ahora pero utilizando una consulta. Los pasos que debemos seguir son los
siguientes:

1.- Creamos una consulta sobre la tabla TClientes2, y la llamamos CClientes2.

2.- Al grid de la consulta aadimos todos los campos (arrastrando el asterisco). A continuacin
arrastramos el campo [IdCli] al grid, desmarcamos el check de Mostrar y en la lnea de
criterios escribimos lo siguiente:

=[Forms]![FMenu].[cboBuscaCliente].[Value]

Como vemos, el filtro en este caso est situado en la propia consulta. Ni que decir tiene que
podramos parametrizar la consulta, o aadirle campos calculados. As, este sistema adquiere
un poquito ms de sentido (si necesitis refrescar el tema de las consultas podis visitar
este link y seleccionar los enlaces de los artculos de consultas).

3.- Creamos un formulario basado en la consulta que acabamos de crear. Lo llamamos


FClientesXConsulta

4.- Volvemos a nuestro FMenu, creamos un nuevo botn de comando (cmdBuscarCliXConsulta)


y le generamos el siguiente codigo:

Private Sub cmdBuscarCliXConsulta_Click()


If IsNull(Me.cboBuscaCliente.Value) Then Exit Sub
DoCmd.OpenForm "FClientesXConsulta", , , , acFormReadOnly
DoCmd.Close acForm, Me.Name
End Sub

6
Vistame en http://siliconproject.com.ar/neckkito/
La primera lnea de cdigo, evidentemente, es de control, para evitar que se ejecute el cdigo
si no hay valor seleccionado en el combo. La segunda abre nuestro formulario en vista Slo
lectura.

Un filtro ms al saco ;)

FILTROS COMPUESTOS
Para poder explicar este punto vamos a necesitar crear una
nueva tabla (a lo rpido) con valores adecuados. As, lo
que vamos a hacer es:

1.- Creamos una tabla, que llamaremos Tventas, con los siguientes campos:

2.- Rellenamos nuestra tabla con datos. Los que yo he introducido han sido los siguientes:

3.- Finalmente, creamos un formulario sobre la tabla TVentas, que llamaremos FVentas.

4.- En nuestro FMenu creamos un cuadro de texto, al que pondremos de nombre txtZona. En
su etiqueta escribimos Introduzca zona (N,S,E,O)

Vamos a aprovechar este ejemplo para practicar un poco el Select Case de una manera muy
simple.

5.- Creamos un cuadro combinado, que llamaremos cboVend, y lo configuraremos a travs del
asistente, dicindole que de la tabla TVentas queremos el valor del campo [Vend]

Como podris ver Access automticamente, en el origen de la fila, nos ha incluido la clave

7
Vistame en http://siliconproject.com.ar/neckkito/
principal de la tabla, aunque no se la hayamos seleccionado. En este caso utilizaremos el
propio nombre del vendedor. A continuacin veremos cmo arreglar este asuntillo.

INCISO: ESE COMBO CON VALORES


REPETIDOS...
Si ahora, sin ms, ponemos FMenu en vista formulario y
desplegamos nuestro cboVend veremos que hay valores
repetidos, lo cual es un poco incordio. Os explico muy
rpidamente cmo podemos solucionar eso:

1.- Sacamos las propiedades del combo y nos vamos a la pestaa Datos Origen de la fila.
2.- Si nos situamos en el espacio en blanco que hay a su derecha . Veremos que nos aparece
un pequeo botn de puntos suspensivos. Hacemos click sobre l.
3.- Nos aparecer la consulta origen de los datos. Vamos a operar sobre dicha consulta, de la
siguiente manera:

Eliminamos la columna correspondiente al campo [Id]


Convertimos la consulta en una consulta de totales, a travs del botn correspondiente
de la cinta de opciones (es el botn con la sigma griega -- )
No hace falta que toquemos las opciones de agrupamiento.

Con lo anterior conseguimos que los valores repetidos aparezcan como nicos.

SIGAMOS....
6.- Con los cambios que hemos realizado en el origen de la fila del combo hemos alterado ese
combo. Para reanimarlo vamos a hacer lo siguiente: sacamos sus propiedades y:
Pestaa Datos Columna dependiente: 1
Pestaa Formato Nmero de columnas: 1
Pestaa Formato Ancho de columnas: eliminamos el 0cm; y dejamos el segundo
valor (en la BD de ejemplo: 2,542cm)

7.- Creamos un botn de comando (cmdFiltroComp), y le generamos el siguiente cdigo:

Private Sub cmdFiltroComp_Click()


Dim vZona As String, vVend As String
Dim miFiltro As String
vZona = Nz(Me.txtZona.Value, "")
vVend = Nz(Me.cboVend.Value, "")
'Controlamos que txtZona y cboVend no estn vacos
If vZona = "" Or vVend = "" Then Exit Sub
'Reconvertimos las iniciales en valores a travs del Select Case
Select Case vZona
Case "N"
vZona = "Norte"
Case "S"
vZona = "Sur"
Case "E"
vZona = "Este"
Case "O"
vZona = "Oeste"
Case Else
MsgBox "El valor introducido para la zona no es

8
Vistame en http://siliconproject.com.ar/neckkito/
correcto", vbExclamation, "NO CORRECTO"
Exit Sub
End Select
'Construimos el filtro
miFiltro = "[Zona]='" & vZona & "'"
miFiltro = miFiltro & " AND [Vend]='" & vVend & "'"
'Cerramos FMenu
DoCmd.Close acForm, Me.Name
'Abrimos FVentas filtrado
DoCmd.OpenForm "FVentas", , , miFiltro,
acFormReadOnly
End Sub

Veamos los puntos a destacar de este cdigo:

Para controlar en una sola lnea de cdigo (If vZona = "" Or vVend = "" Then Exit Sub)
si se han introducido valores hemos utilizado un operador lgico: OR. De ah que con esa lnea
matemos dos pjaros de un tiro, si no nos interesa un mayor nivel de control.
Hemos utilizado el Select Case de manera que tambin nos mata dos pjaros de un
tiro. Es decir, realiza una primera funcin de conversin (transforma las iniciales de las zonas
en sus nombres completos), pero tambin realiza una segunda funcin de control, a travs del
CASE ELSE, que detecta si el usuario introduce un valor no permitido.
Construimos el filtro por partes. Lgicamente se podra haber construido el filtro en una
sola lnea, pero yo no lo he hecho as por varios motivos:
Por motivos didcticos
Para que podis ver como vamos reutilizando la misma variable.
Porque si utilizamos una sola lnea el cdigo puede llegar a ser difcil de leer, o
como mnimo incmodo, si la lnea nos sale de la pantalla y debemos desplazarnos con
la barra de desplazamiento horizontal.
Finalmente, vemos que si tenemos el filtro almacenado en una variable en la lnea del
DoCmd.OpenForm, en el espacio reservado al argumento para el filtro, simplemente escribimos
directamente esa variable.

En el cdigo he abierto el formulario como slo lectura, pero evidentemente vosotros ya sabis
cmo abrirlo para editarlo, por ejemplo.

FILTRO PARAMETRIZADO
Puede ser que en algn momento necesitemos un parmetro que deba ser rellenado por el
usuario. Como ya sabemos (o si no lo sabemos lo aprenderemos ahora) un parmetro viene
configurado por la siguiente secuencia de caracteres:

Corchete de apertura-Comillas dobles-Mensaje-Comillas dobles-Corchete de cierre

Si hemos seguido los valores de la BD de ejemplo veremos que hay un registro que nos dice
que el vendedor Hulk, en la zona Norte, en Bilbao, ha vendido por 3.000 euros. Vamos a
aadir un nuevo registro en TVentas de manera que:

Hulk, en la zona Norte, en Andorra, ha vendido por 1.500 euros

E imaginemos que queremos saber en qu ciudades ha vendido Hulk por encima de los 2.000
euros.

Una manera de hacerlo sera introducir un InputBox, pedir la informacin del importe de venta
lmite al usuario y aadir ese valor al filtro. Como en teora esto ya lo deberamos saber hacer

9
Vistame en http://siliconproject.com.ar/neckkito/
(os animo a que lo probis, a ver si os sale, pero despus de leer el resto de este punto por un
detalle que explicar ms adelante).

Otra manera sera construirnos y utilizar un parmetro.


Para ello vamos a seguir el siguiente proceso:

Creamos uno a uno los elementos del parmetro


Aadimos de manera correcta el parmetro a
nuestro filtro.

Eso es la parte terica. La aplicacin prctica sera as:

1.- Creamos, en FMenu, un nuevo botn de comando (cmdFiltroCompParam), y le generamos


el siguiente cdigo, muy parecido al anterior:

Private Sub cmdFiltroCompParam_Click()


Dim vZona As String, vVend As String
Dim miFiltro As String
vZona = Nz(Me.txtZona.Value, "")
vVend = Nz(Me.cboVend.Value, "")
'Controlamos que txtZona y cboVend no estn vacos
If vZona = "" Or vVend = "" Then Exit Sub
'Reconvertimos las iniciales en valores a travs del Select Case
Select Case vZona
Case "N"
vZona = "Norte"
Case "S"
vZona = "Sur"
Case "E"
vZona = "Este"
Case "O"
vZona = "Oeste"
Case Else
MsgBox "El valor introducido para la zona no es correcto", vbExclamation, "NO
CORRECTO"
Exit Sub
End Select
'Construimos el filtro
miFiltro = "[Zona]='" & vZona & "'"
miFiltro = miFiltro & " AND [Vend]='" & vVend & "'"
miFiltro = miFiltro & " AND [ImpVta]>=" & "[" & "Importe mayor que:?" & "]"
'Cerramos FMenu
DoCmd.Close acForm, Me.Name
'Abrimos FVentas filtrado
DoCmd.OpenForm "FVentas", acFormDS, , miFiltro, acFormReadOnly
End Sub

Como vemos en la primera lnea marcada en negrita, hemos aadido una tercera lnea para la
construccin del filtro y hemos construido un parmetro para que al usuario le salga una casilla
con la pregunta del milln.

Fijaos tambin que:


Los filtros con variables tipo String los hemos encerrado entre comillas simples.
En el filtro del parmetro, que representa un valor

10
Vistame en http://siliconproject.com.ar/neckkito/
de tipo Currency (y lo mismo para variables de tipo
numrico), no hemos encerrado el valor entre comillas, sino
que lo hemos aadido directamente. Debis tenerlo en
cuenta por lo que os propona de utilizar un InputBox y
aplicar sobre la variable que recoja el valor introducido el
filtro
Estamos uniendo los filtros a travs de AND. Tened
en cuenta que no hay problema, si nos interesa, en utilizar
el OR, o una combinacin de los dos operadores lgicos.
Os he marcado la ltima lnea como recordatorio de
algo que ya sabemos: podemos manipular la vista del
formulario desde el cdigo. En este caso lo hemos abierto
en vista hoja de datos (acFormDS).

Si el usuario cancela la introduccin del parmetro nos saltar un error. En un captulo


posterior veremos cmo controlar estos errores.

UN POCO MS SOBRE FILTROS COMPUESTOS


Vamos a complicar nuestro ejemplo. De hecho, vamos a jugar a configurar combinaciones de
filtros.

Vamos a aadir en FMenu un cuadro de texto, al que llamaremos txtImport, donde


introduciremos (si queremos) el importe de la venta que ser nuestro lmite inferior (es decir,
que filtraremos por mayor o igual que)

En el punto anterior hemos visto como era necesario rellenar el campo zona y el campo
vendedor para que actuara el cdigo. Ahora vamos a ver cmo podemos crear filtros si
rellenamos todos los campos, slo algunos o los dejamos en blanco.

Vamos a intentar explicarlo un poco en abstracto, primero, para entender la mecnica de


funcionamiento. Despus veremos cmo aplicarlo en el cdigo. El truco est en el AND que une
los criterios de filtro. Si establecemos una prelacin de orden de campos, el AND nos aparecer
en funcin de si hay valor en el campo previo.

S que esto es un poco lioso, pero con el cdigo lo veremos ms claro (espero!). Pondr
muchos comentarios en el cdigo para que podis entender el proceso:

Vmonos pues...

1.- Creamos un nuevo botn de comando (cmdFiltro3Controles). Le generamos el siguiente


cdigo:

Private Sub cmdFiltro3Controles_Click()


Dim vZona As String, vVend As String
Dim vImport As Currency
Dim miFiltro As String
vZona = Nz(Me.txtZona.Value, "")
vVend = Nz(Me.cboVend.Value, "")
vImport = Nz(Me.txtImport.Value, -1)

'El primer filtro es fcil. Si no hay valor en ninguno de los controles abrimos el formulario
sin filtrar
If vZona = "" And vVend = "" And vImport = -1 Then
DoCmd.Close acForm, Me.Name
DoCmd.OpenForm "FVentas", acFormDS, , , acFormReadOnly

11
Vistame en http://siliconproject.com.ar/neckkito/
Exit Sub
End If

'Inicializamos el filtro
miFiltro = ""

'Establezcamos un orden de prelacin: 1-Zona / 2-


Vendedor / 3-Importe
'Analizamos primero la zona
If vZona <> "" Then
Select Case vZona
Case "N"
vZona = "Norte"
Case "S"
vZona = "Sur"
Case "E"
vZona = "Este"
Case "O"
vZona = "Oeste"
Case Else
MsgBox "El valor introducido para la zona no es correcto", vbExclamation, "NO
CORRECTO"
Exit Sub
End Select
'Creamos la primera parte del filtro
miFiltro = "[Zona]='" & vZona & "'"
End If

'Analizamos el segundo elemento: Vendedor, teniendo en cuenta que:


'Si vZona est lleno el filtro Vendedor deber llevar AND
'Si vZona est vaco el filtro Vendedor no llevar AND
If vVend <> "" Then
If vZona <> "" Then
'Creamos el filtro para este supuesto: hay valor en zona AND hay valor en vendedor
miFiltro = miFiltro & " AND [Vend]='" & vVend & "'"
Else
'Creamos el filtro para este supuesto: no hay valor en zona pero s valor en
vendedor
miFiltro = "[Vend]='" & vVend & "'"
End If
End If

'Analizamos el tercer elemento: Importe, teniendo en cuenta que debemos analizar:


'Si vVend est lleno el filtro del importe necesita AND
'Si vVend no est lleno debemos mirar si vZona est lleno. Si lo est debe llevar AND
'Si vImport es el nico control relleno no debe llevar AND
If vImport >= 0 Then
'Hay valor en el control vendedor
If vVend <> "" Then
miFiltro = miFiltro & " AND [ImpVta]>=" & txtImport
Else
'No hay valor en el control vendedor. Miramos si hay valor en zona
If vZona <> "" Then
'Hay valor en zona
miFiltro = miFiltro & " AND [ImpVta]>=" & txtImport
Else

12
Vistame en http://siliconproject.com.ar/neckkito/
'No hay valor en zona
miFiltro = miFiltro & "[ImpVta]>=" & txtImport
End If
End If
End If

'Tened en cuenta que si no hay valor en ninguno de


los controles no hemos modificado el filtro,
'por lo que el valor del filtro es el mismo con que lo
hemos inicializado, es decir, una cadena vaca

'Cerramos el formulario FMenu


DoCmd.Close acForm, Me.Name
'Abrimos el formulario FVentas aplicando el filtro
DoCmd.OpenForm "FVentas", acFormDS, , miFiltro, acFormReadOnly
End Sub

Bueno... creo que tendris un buen rato para analizar este cdigo. Como siempre, la idea es
que cojis la mecnica para que podis aplicarla en vuestras BD's... si el dolor de cabeza os lo
permite! Je, je...

Bromas aparte, el cdigo est comentado, por lo que no aadir ms lea a este punto. Slo
recalcar, si me permits, que la variable vImport coge su valor a travs de la funcin NZ, que
en caso de no tener valor devuelve -1. Recordad que como hemos definido vImport como
Currency el valor si nulo debe ser compatible con este tipo de datos.

FILTRO EN EL PROPIO FORMULARIO

A TRAVS DE UN FILTERON
Ahora vamos a ver cmo utilizar un filtro en el propio formulario. Vamos a preparar el terreno:

1.- Copiamos nuestro formulario FVentas y lo pegamos como FVentas2.

2.- Para ver mejor los efectos vamos a cambiar la vista predeterminada de FVentas2. Sacamos
sus propiedades y nos vamos a la pestaa Formato Vista predeterminada Formularios
continuos.

3.- En la cabecera del formulario aadimos un cuadro de texto, que llamaremos txtFiltro. Ah
escribiremos el nombre del vendedor sobre el que queremos ver los registros.

4.- Aadimos tambin un botn de comando, que llamaremos cmdEjecutaFiltro.

Muy bien. Vamos a ver cmo programamos nuestro botn. El cdigo sera el siguiente.

Private Sub cmdEjecutaFiltro_Click()


Dim vVend As String, miFiltro As String
vVend = Nz(Me.txtFiltro.Value, "")
If vVend = "" Then Exit Sub
'Construimos el filtro
miFiltro = "[Vend]='" & vVend & "'"
'Aplicamos el filtro al formulario
Me.Filter = miFiltro

13
Vistame en http://siliconproject.com.ar/neckkito/
'Activamos el filtro
Me.FilterOn = True
End Sub

Como vemos, el proceso se realiza en tres etapas:

1.- Construimos el filtro


2.- Aplicamos el filtro al formulario a travs de Me.Filter
3.- Activamos el filtro a travs de Me.FilterOn = True

Fcil, verdad?

Si ahora aadimos otro botn de comando (cmdQuitaFiltro) podemos generar el siguiente


cdigo para desactivar el filtro:

Private Sub cmdQuitaFiltro_Click()


Me.txtFiltro.Value = Null
Me.FilterOn = False
End Sub

UTILIZACIN DEL LIKE


Qu ocurrira si queremos buscar un valor del que slo conocemos una parte del nombre?
Pues para ello tenemos una palabrita mgica, que es LIKE.

El LIKE nos permite buscar partes en los valores de los registros, y nos muestra las
coincidencias. Debemos combinarlo con caracteres comodn, de manera que utilizaremos:

El asterisco (*) para cualquier cadena de caracteres, incluyendo cadena vaca.


El interrogante de cierre (?) para un carcter cualquiera
La almohadilla (#) para un dgito cualquiera.

Vamos a ver cmo aplicarlo a nuestra BD: en un nuevo botn de comando (cmdLike), en
FVentas2, generamos el siguiente cdigo:

Private Sub cmdLike_Click()


Dim vVend As String, miFiltro As String
vVend = Nz(Me.txtFiltro.Value, "")
If vVend = "" Then Exit Sub
'Construimos el filtro
miFiltro = "[Vend] LIKE '*" & vVend & "*'"
'Aplicamos el filtro al formulario
Me.Filter = miFiltro
'Activamos el filtro
Me.FilterOn = True
End Sub

Como vemos, hemos creado un filtro que, a travs de los asteriscos como caracteres comodn,
nos busca a comienzo, en medio y a final del valor. Jugando con esos comodines podemos
indicarle que:

14
Vistame en http://siliconproject.com.ar/neckkito/
Queremos que coincida el inicio del valor: LIKE xxx*
Queremos que coincida el final del valor: LIKE *xxx

Tened tambin cuidado, si la variable es String, de utilizar


correctamente las comillas simples.

Finalmente, y como comentario general, pensad que


podramos haber utilizado el LIKE en cualquiera de los
ejemplos de cdigo de este captulo (es decir, no es
exclusivo del FilterOn).

A TRAVS DE UN CLON DEL RECORDSET DEL FORMULARIO


No vamos a entrar en este captulo con una explicacin de lo que es un recordset. Dejmoslo,
como idea a nuestros efectos, que en nuestro caso el recordset representa el conjunto de
registros sobre los que se basa nuestro formulario; en definitiva, los registros de la tabla
TVentas.

Vamos a suponer que queremos encontrar la ficha de un cliente a travs de un combo en el


propio formulario. Lo que vamos a hacer va a ser lo siguiente:

1.- Vamos a copiar nuestro formulario FClientes2 y lo vamos a pegar como FClientes3

2.- En la cabecera de FClientes3 aadimos un cuadro combinado. Le decimos que queremos,


de la tabla TClientes2, el nombre del cliente, ocultamos la clave principal y queremos recordar
el valor para utilizarlo ms adelante.

3.- A ese combo le ponemos de nombre cboFiltraCli

4.- En el evento Despus de actualizar le generamos el siguiente cdigo:

Private Sub cboFiltraCli_AfterUpdate()


Dim vCli As Long
Dim miFiltro As String
Dim rst As Recordset
vCli = Nz(Me.cboFiltraCli.Value, 0)
If vCli = 0 Then Exit Sub
'Construimos el filtro
miFiltro = "[IdCli]=" & vCli
'Clonamos el recordset del formulario
Set rst = Me.Recordset.Clone
'Buscamos el valor del filtro. Eso nos dar un marcador en el recordset
rst.FindFirst (miFiltro)
'Pasamos el marcador del recordset como marcador del formulario
Me.Bookmark = rst.Bookmark
End Sub

El asunto est en que un recordset permite una flexibilidad amplsima a la hora de ser
manipulado, de ah que nos sirvamos del mismo. Debemos considerar, adems que:

Este sistema nos hace las veces de filtro porque estamos operando sobre un valor
nico; esto es, el campo clave.
Si el valor no fuera nico (es decir, se pudiera repetir) lo que hara este cdigo es
llevarnos al primer registro coincidente (a travs del FindFirst)

15
Vistame en http://siliconproject.com.ar/neckkito/
Como hemos operado a travs de un combo con
todos los valores a buscar posibles, y que adems no
permite ediciones ni adiciones de valores, el anterior cdigo
nos funcionar de perlas. Pero, qu pasara si no
existiera el valor buscado?

NUESTRO CLON NO ENCUENTRA EL VALOR


Vamos a abrir nuestro FClientes3 en vista diseo y vamos a aadir
un cuadro de texto, que llamaremos txtBusca.

Sacamos sus propiedades y nos vamos a la pestaa Eventos Despus de actualizar, y


generamos el siguiente evento2:

Private Sub txtBusca_AfterUpdate()


Dim vCli As String
Dim miFiltro As String
Dim rst As Recordset
vCli = Nz(Me.txtBusca.Value, "")
If vCli = "" Then Exit Sub
'Construimos el filtro
miFiltro = "[NomCli]='" & vCli & "'"
'Clonamos el recordset del formulario
Set rst = Me.Recordset.Clone
'Buscamos el valor del filtro. Eso nos dar un marcador en el recordset
rst.FindFirst (miFiltro)
'Pasamos el marcador del recordset como marcador del formulario
Me.Bookmark = rst.Bookmark
If rst.NoMatch Then
MsgBox "El cliente introducido no existe!", vbExclamation, "SIN DATOS"
End If
End Sub

Como vemos, el cdigo es prcticamente similar al anterior (adaptndolo al hecho de que


ahora buscamos un String), pero le hemos aadido un IF de control por si el valor no existiera.
Y esto el cdigo lo detecta a travs de rst.NoMatch

MS ALL DE LOS FILTROS: CONTROLES Y LA PROPIEDAD


ROWSOURCE
Hasta ahora hemos visto filtros que afectaban a formularios e informes. Sin embargo, existen
controles que poseen la propiedad Rowsource (origen de la fila) que tambin pueden ser
manipulables a travs de cdigo, en el cual los filtros pueden tener influencia. Lgicamente
aprovecharemos la coyuntura para realizar un anlisis un poco ms exhaustivo de estos
controles, que ir un poco ms all de los filtros puros y duros.

Nos centraremos en los cuadros combinados, aunque los cuadros de lista son prcticamente
iguales.

2 Si tenemos algn problema con el funcionamiento del cdigo debemos comprobar que tengamos registrada la referencia Microsoft
DAO 3.6 Object Library

16
Vistame en http://siliconproject.com.ar/neckkito/
TIPOS DE ROWSOURCE

Podemos encontrarnos con tres tipos de origen de la fila:

Datos que provienen de una tabla o de una consulta


Datos que provienen de una lista de valores
Datos que provienen de una lista de campos

Vamos a verlos, pero antes, en nuestra BD, vamos a crear


un formulario en blanco, al que llamaremos FControles. Ese
formulario nos servir para ir aplicando nuestros
conocimientos.

DATOS LISTA DE VALORES


La lista de valores son una serie de valores independientes que nosotros definimos en el
combo. Vamos a ver cmo podemos hacerlo:

1.- En FControles creamos un cuadro combinado, al que pondremos por nombre cboValores.
Cuando nos salga el asistente lo cancelamos.
2.- Sacamos las propiedades de ese combo y nos vamos a la pestaa Datos Tipo de origen
de la fila. Ah seleccionamos Lista de valores

3.- En la misma pestaa Origen de la fila, podremos escribir los valores que queremos que
muestre el combo. Esos valores deben ir separados por punto y coma (;). Por ejemplo,
escribimos ah: Lunes; Martes; Mircoles.

4.- Si ahora ponemos nuestro formulario en vista formulario veremos que nuestro combo nos
muestra los valores que hemos introducido.

5.- Si volvemos a la vista diseo, comprobamos que las propiedades Limitar a la lista est
fijada en S.

Vamos a ver cmo podemos ir ampliando, a travs de cdigo, nuestra lista de valores. Para ello
nos vamos a la Pestaa Eventos Al no estar en la lista, y generamos el siguiente cdigo:

Private Sub cboValores_NotInList(NewData As String, Response As Integer)


Dim resp As Integer
Dim miRowSce As String
'Como el propio evento detectar que no est en la lista aprovechamos
'el mismo para lanzar un mensaje de advertencia y pedir al usuario si
'desea aadirlo
resp = MsgBox("El valor introducido no est en la lista. Desea aadirlo?", _
vbQuestion + vbYesNo, "VALOR NUEVO")
'Si la respuesta es NO asignamos valor al argumento RESPONSE
'y salimos del proceso
If resp = vbNo Then
Response = acDataErrContinue
Exit Sub
Else
'Si la respuesta es S lo aadimos...
'Asignamos valor al argumento RESPONSE
Response = acDataErrAdded
'Cogemos el RowSource actual del combo
miRowSce = Me.cboValores.RowSource

17
Vistame en http://siliconproject.com.ar/neckkito/
'Aadimos el nuevo elemento
miRowSce = miRowSce & ";" & NewData
'Aplicamos el nuevo rowsource al combo
Me.cboValores.RowSource = miRowSce
End If
End Sub

Veamos:

.- El evento Not in list tiene dos argumentos: NewData y


Response. NewData recoge el valor introducido (y que no est en
la lista). Response espera que el usuario le indique qu debe hacer
con el nuevo valor. Al producirse el evento debemos asignar un
valor a estos dos elementos en funcin de lo que decidamos.

.- Para saber qu quiere hacer el usuario creamos la variable resp, que recoge dicha
contestacin a travs del botn que pulse el usuario en un MsgBox.

.- Si el usuario responde que no debemos indicarle al cdigo que Response coge el valor de
una constante de VB, que es acDataErrContinue, para que inmediatamente le digamos que no
haga nada y que salga del proceso.

.- Si el usuario responde que S debemos decirle que Response coger el valor, a travs de una
constante, que es acDataErrAdded.

.- A continuacin manejamos el Rowsource con una secuencia que, como vemos en el cdigo,
es lgica:
.- Cogemos el RowSource actual
.- Lo modificamos, aadindole el nuevo valor (que, no olvidemos, est recogido ya
directamente por el argumento del evento NewData)
.- Asignamos el nuevo RowSource modificado a nuestro combo.

Debemos tener en cuenta que estas adiciones de valores se realizan en tiempo de ejecucin;
es decir, se aaden slo en la sesin de trabajo. Si cerramos el formulario y lo volvemos a abrir
los valores del RowSource volvern a ser los originales (de lunes a mircoles).

Evidentemente podramos programar el evento Despus de actualizar, por ejemplo, para


ejecutar las acciones que necesitemos con el valor introducido. Por ejemplo, para ver los
resultados, programamos el siguiente cdigo:

Private Sub cboValores_AfterUpdate()


MsgBox "El valor seleccionado ha sido " & Me.cboValores.Value, vbInformation, "MENSAJE"
End Sub

Y si queremos que estas adiciones sean permanentes? En ese caso los valores debern estar
guardados en una tabla...

DATOS TABLA/CONSULTA
1.- Vamos a crear una tabla, que llamaremos TDias, con dos campos:
[Dia] de tipo texto. No ponemos ninguna clave principal.
[Festivo] de tipo S/No, con el valor por defecto cero (0) o False

18
Vistame en http://siliconproject.com.ar/neckkito/
En ella introducimos tres registros con nuestros tres das: Lunes, Martes y Mircoles.

2.- En FControles aadimos un nuevo combo, que


llamaremos cboTDias. Cuando nos salga el asistente le
decimos que queremos, de la tabla TDias, el campo [Dia]

3.- Sacamos las propiedades del combo y en la pestaa


Datos Limitar a la lista, le decimos que S.

Vamos a ver cmo podemos aadir das que no estn en la


lista. Para ello utilizaremos una SQL de datos anexados3,
fcil de entender aunque, a simple vista, parezca difcil de
construir.

As pues, en la pestaa Eventos Al no estar en la lista, le generamos el siguiente cdigo:

Private Sub cboTDias_NotInList(NewData As String, Response As Integer)


Dim resp As Integer
Dim miSql As String
Dim diaNuevo As String
'Como el propio evento detectar que no est en la lista aprovechamos
'el mismo para lanzar un mensaje de advertencia y pedir al usuario si
'desea aadirlo
resp = MsgBox("El valor introducido no est en la lista. Desea aadirlo?", _
vbQuestion + vbYesNo, "VALOR NUEVO")
'Si la respuesta es NO asignamos valor al argumento RESPONSE
'y salimos del proceso
If resp = vbNo Then
Response = acDataErrContinue
Exit Sub
Else
'Si la respuesta es S lo aadimos...
'Asignamos valor al argumento RESPONSE y a la variable diaNuevo
Response = acDataErrAdded
diaNuevo = NewData
'Creamos la SQL
miSql = "INSERT INTO TDias(Dia) SELECT " & """" & diaNuevo & """" & " AS NuevoDia"
'Desactivamos los Warnings
DoCmd.SetWarnings False
'Ejecutamos la consulta
DoCmd.RunSQL (miSql)
'Activamos los Warnings
DoCmd.SetWarnings True
End If
End Sub

Vamos a fijarnos en la parte final del cdigo, cuando el usuario pulsa el botn S:

.- Pasamos el valor de NewData a una variable: diaNuevo


.- Creamos la SQL de datos anexados. Como necesitamos que diaNuevo nos aparezca entre
comillas necesitamos aadir las cuatro comillas delante y detrs de la variable.
.- Si no desactivramos los Warnings nos saldra eso de Va a anexar 1 fila a.... Como sera
muy molesto recibir cada vez dicho mensaje lo desactivamos.

3 Cuando veamos el captulo dedicado al Recordset veremos cmo incluir valores a travs de un recordset

19
Vistame en http://siliconproject.com.ar/neckkito/
.- Ejecutamos la SQL
.- Volvemos a activar los Warnings. Es importante volverlos
a activar porque la desactivacin no slo afecta al cdigo
que estamos programando, sino a todos los cdigos. Si se
produjera pues algo raro en nuestra BD no nos saldran
los mensajes de advertencia, con lo que perderamos
informacin (muy importante a veces) para saber qu est
pasando.

Como veis, adems de aprender cmo aadir un valor en la


tabla podemos apuntarnos un par de cosas tiles para
nuestros cdigos:

Activar y desactivar avisos: DoCmd.SetWarnings True/False


Ejecutar una SQL: DoCmd.RunSql (nombreSql)

MODIFICAR EL ORIGEN SI EL TIPO DE DATOS ES DE TABLA O CONSULTA


Vamos (si no lo hemos hecho ya) a introducir dos registros directamente en nuestra tabla
TDias. Introduciremos:

Sbado Marcaremos el check de festivo


Domingo Marcaremos el check de festivo.

Ahora lo que vamos a hacer es introducir en nuestro formulario un marco de opciones, con dos
opciones (que llamaremos mrcFestivos): la opcin 1, que sern los das festivos, y la opcin 2,
que sern los das no festivos. Por si alguien no tiene claro cmo se hace eso lo explico paso a
paso:

1.- Con FControles en vista diseo, aadimos un marco de opciones. Nos saldr el asistente. Lo
configuramos de la siguiente manera:

Nombres de las etiquetas: en la primera lnea escribimos Mostrar festivos; en la


segunda lnea escribimos Mostrar hbiles
Podemos seleccionar la opcin predeterminada a nuestro gusto. Para el ejemplo yo he
dicho que no quera opcin predeterminada.
Dejamos los valores que salen por defecto, 1 y 2
Configuramos el diseo del marco a nuestro gusto
Como ttulo ponemos, por ejemplo, Filtrar por:

2.- No olvidemos cambiar el nombre a nuestro marco (Propiedades Pestaa Otras


Nombre)

3.- En sus propiedades nos vamos a la pestaa Eventos Despus de actualizar, y generamos
el siguiente cdigo:

Private Sub mrcFestivos_AfterUpdate()


Dim vOpc As Integer
Dim miRowSce As String
vOpc = Me.mrcFestivos.Value
'Generamos la parte comn de miRowSce, sea cual sea la opcin seleccionada
miRowSce = "SELECT TDias.Dia FROM TDias"
'Analizamos la opcin seleccionada
If vOpc = 1 Then
'Aadimos el filtro que nos interesa para filtrar por festivos

20
Vistame en http://siliconproject.com.ar/neckkito/
miRowSce = miRowSce & " WHERE [Festivo]=TRUE"
Else
'Configuramos el filtro para filtrar por no festivos
miRowSce = miRowSce & " WHERE [Festivo]=FALSE"
End If
With Me.cboTDias
'Asignamos el nuevo rowsource a nuestro combo
cbo TDias
.RowSource = miRowSce
'Refrescamos el combo
.Requery
End With
End Sub

Vaya, vaya... vuelve a aparecer nuestro amigo el filtro, en este caso no para filtrar los datos
que mostrar un formulario sino ahora para filtrar los datos que mostrar un combo.

El cdigo est comentado, y con todo lo que hemos aprendido hasta ahora no deberamos
tener ningn problema para entenderlo (y aplicarlo a nuestras BD's... je, je...).

DATOS LISTA DE CAMPOS


Finalmente vamos a ver la ltima opcin, que es una lista de campos. Para ello, vamos a
practicar lo anterior de la siguiente manera:

1.- En FControles creamos un cuadro combinado, que llamaremos cboCampos. Cancelamos el


asistente.

2.- Creamos un cuadro de lista, que llamaremos lstDatos. Cancelamos el asistente.

3.- Sacamos las propiedades de cboCampos y nos vamos a la pestaa Datos Tipo de origen
de la fila. Seleccionamos la opcin Lista de campos.

4.- Ahora, si nos situamos en la propiedad Origen de la fila, nos saldr una lista con las tablas
y consultas que tengamos en nuestra BD. Nosotros seleccionamos, por ejemplo, la tabla
TVentas.

5.- Si situamos FControles en vista Formulario y desplegamos ese combo veremos que nos
muestra los campos de la tabla TVentas.

Una idea sera prepararnos una consulta con los campos que nos pudieran interesar, sin
mostrar campos que no nos sirven para nada. Para no hacer tan largo el ejemplo lo
dejaremos as como est, directamente de la tabla TVentas.

Vamos a ver qu podemos hacer con eso.

6.- De nuestro cboCampos, en el evento Despus de actualizar, generamos el siguiente


evento:

Private Sub cboCampos_AfterUpdate()


Dim vCampo As String, miRowSce As String
vCampo = Me.cboCampos.Value
If vCampo = "" Then
'Si no hay valor en el combo no hay valores en la lista

21
Vistame en http://siliconproject.com.ar/neckkito/
Me.lstDatos.RowSource = ""
Else
'Si hay valor en el combo el cuadro de lista nos mostrar los
'valores del campo seleccionado
miRowSce = "SELECT TVentas." & vCampo & " FROM
TVentas"
'Aplicamos el rowsource al cuadro de lista
Me.lstDatos.RowSource = miRowSce
End If
'Refrescamos el cuadro de lista
Me.lstDatos.Requery
End Sub

Creo que, a estas alturas, no hace falta explicar el cdigo anterior. Como vemos, la mecnica,
si se trata de un cuadro de lista, es prcticamente igual a como hemos tratado los combos. De
hecho, este ejemplo combina ambos tipos de controles.

LOS INFORMES Y LA PROPIEDAD RECORDSOURCE


Vamos a hacer unos cambios en la BD, y despus entraremos en la explicacin:

1.- Copiamos nuestra tabla TVentas (estructura y datos) y la pegamos con el nombre de
TVentasHistorico.

2.- Abrimos la tabla TVentasHistorico y modificamos algunos registros (simplemente para


poder apreciar la diferencia entre una tabla y otra).

3.- Creamos un informe sobre la tabla TVentas, y lo llamamos RVentas.

Bueno... pues al crear ese informe sobre TVentas lo que estamos haciendo, aunque no lo
sepamos, es indicar al informe que su Recordsource es TVentas.

La gracia de toquetear el recordsource de un informe es que slo lo podemos hacer en


vista diseo. Podramos pues modificarlo a travs de cdigo?

La respuesta a esta vital pregunta tendr que esperar, puesto que os voy a decir para qu
hemos hecho todo lo anterior. Imaginemos que tenemos una tabla que nos recoge las ventas
actuales (TVentas) y las ventas de aos pasados las vamos guardando en otra tabla
(TVentasHistorico). De vez en cuando necesitamos sacar un informe de ventas histrico. La
pregunta del milln es: necesitamos crear dos informes?

Y la respuesta es... no. Por qu? Porque s podemos actuar sobre el recordsource del informe,
aunque deba configurarse en vista diseo. Con esto contestamos a nuestra primera pregunta
de dos prrafos ms arriba.

Vamos a ver cmo podemos hacerlo:

1.- En nuestro formulario FMenu aadimos un botn de comando, que llamaremos


cmdAbreRVentas.

2.- Junto a ese botn insertaremos una casilla de verificacin, que llamaremos chkHist.

3.- Sacamos las propiedades de chkHist y nos vamos a la pestaa Datos Valor
predeterminado, y le escribimos FALSE

22
Vistame en http://siliconproject.com.ar/neckkito/
4.- Ahora a nuestro botn de comando le generamos el siguiente cdigo:


Private Sub cmdAbreRVentas_Click()
Dim vOpc As Boolean
Dim miRcdSce As String
'Miramos el valor del botn de opcin
vOpc = Me.chkHist.Value
'Construimos la parte comn del recordsource
miRcdSce = "SELECT * FROM"
'Actuamos segn est marcado o no el botn de opcin
If vOpc = True Then
'Construimos la parte especfica del recordsource
miRcdSce = miRcdSce & " TVentasHistorico"
Else
miRcdSce = miRcdSce & " TVentas"
End If
'Abrimos el informe en vista diseo y oculto
DoCmd.OpenReport "RVentas", acViewDesign, , , acHidden
'Cambiamos su recordsource
Reports!RVentas.RecordSource = miRcdSce
'Cerramos el informe guardando los cambios (sin pedrselo al usuario)
DoCmd.Close acReport, "RVentas", acSaveYes
'Abrimos el informe en vista preliminar
DoCmd.OpenReport "RVentas", acViewPreview
End Sub

El cdigo est comentado paso a paso y poco queda por comentar, exceptuando que, os
recuerdo, as como hemos construido un recordsource con todos los campos tambin
podramos haber aplicado filtros para personalizar an ms el informe (con un marco de
opciones, quizs?).

LO MISMO, PERO CON UN FORMULARIO


Os animo a que probis a construir un cdigo en un botn de comando
(cmdAbreFVentasRcdSce), aprovechando el check que acabamos de construir, para abrir el
formulario FVentas2. Yo os indico a continuacin cmo seria el cdigo (comentado), pero creo
que sera un buen ejercicio intentar hacerlo por vosotros mismos.

Pues lo dicho; el cdigo sera:

Private Sub cmdAbreFVentasRcdSce_Click()


Dim vOpc As Boolean
Dim miRcdSce As String
'Miramos el valor del botn de opcin
vOpc = Me.chkHist.Value
'Construimos la parte comn del recordsource
miRcdSce = "SELECT * FROM"
'Actuamos segn est marcado o no el botn de opcin
If vOpc = True Then
'Construimos la parte especfica del recordsource
miRcdSce = miRcdSce & " TVentasHistorico"
Else
miRcdSce = miRcdSce & " TVentas"
End If

23
Vistame en http://siliconproject.com.ar/neckkito/
'Abrimos el formulario en vista diseo y oculto
DoCmd.OpenForm "FVentas2", acViewDesign, , , acHidden
'Cambiamos su recordsource
Forms!FVentas2.RecordSource = miRcdSce
'Cerramos el formulario guardando los cambios (sin
pedrselo al usuario)
DoCmd.Close acForm, "FVentas2", acSaveYes
'Cerramos FMenu
DoCmd.Close acForm, Me.Name
'Abrimos el formuario en vista slo lectura
DoCmd.OpenForm "FVentas2", , , , acFormReadOnly
End Sub

UNAS PALABRAS FINALES


En este captulo hemos visto cmo construir filtros de diversas maneras, con diferentes
tcnicas, en diferentes lugares, y tambin hemos visto cmo podamos cambiar los rowsource
de algunos controles para acabar viendo cmo modificar el recordsource de un informe
(extensible a un recordsource de un formulario).

Con un poco de imaginacin podemos personalizar nuestros formularios, controles (combos y


listas) y nuestros informes de manera que muestren, cada vez, la informacin que
necesitemos, en vez de crearnos controles y ms controles, o informes y ms informes, uno
para cada cosa. Con ello nuestra BD saldr ganando en tamao y en estilo.

Espero que lo aprendido aqu os sea til.

Suerte!

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

Vous aimerez peut-être aussi