Documentos de Académico
Documentos de Profesional
Documentos de Cultura
CuadrosCombinados PDF
CuadrosCombinados PDF
INTRODUCCIÓN
Nuestro amigo Sveinbjorn nos ha
preparado un excelente ejemplo de
múltiples maneras de tomar datos de un
cuadro combinado y manejarlos tanto a través de código
VBA como de funciones y expresiones. Es un ejemplo de
estudio que no tiene desperdicio.
Todo el texto que leeréis a partir del siguiente apartado es trabajo de Sveinbjorn, así como la
BD que acompaña este ejemplo. Oséase, que el mérito y las alabanzas deben ser para él. A mí
sólo me queda el agradecerle esta preparación que me haya permitido compartir este ejemplo
con vosotros.
CUADROS COMBINADOS
Una duda muy habitual en los foros trata sobre los cuadros combinados, concretamente ¿cómo puedo
mostrar un valor en un cuadro de texto que dependa del valor elegido en un cuadro combinado?
Como hay distintas formas de conseguir este efecto, las voy a agrupar todas en un mismo ejemplo,
explicando sus pros y contras. Este ejemplo es aplicable a cuadros de listas, y en menor medida a cuadros
de texto.
PREPARATIVOS
En primera instancia, vamos a partir de la tabla del ejemplo Combos en Cascada, para explicar las
distintas formas de responder a la pregunta. Es una tabla muy sencilla, con tres campos: Pais, Prov y Pobl,
para introducir, respectivamente, países, provincias y poblaciones.
En segunda instancia, vamos a “complicar” un poco más el asunto, trabajando con dos tablas
relacionadas: TCCAA, con campos CodCA y Comunidad, y TProvincias, con campos CodProv, Provincia y
CCAA (éste relacionado con CodCA de TCCAA)
1
Visítame en http://neckkito.siliconproject.com.ar
1ª OPCIÓN: FUNCIÓN DBÚSQ (O DLOOKUP):
Vamos a crear un formulario en blanco, que llamaremos FEjemplo01, y en él vamos a insertar un
cuadro combinado para elegir una población, y dos cuadros de texto, que nos mostrarán la provincia y el
país de la población elegida. A estos cuadros los llamaremos respectivamente cboPobl, txtProv y txtPais.
El cuadro combinado, lo podemos crear usando el asistente, en cuyo caso le decimos que
queremos usar una tabla (TDatos), y seleccionamos el campo [Pobl] y configuramos a nuestro gusto hasta
el final; o lo podemos crear “a las bravas”, trabajando directamente sobre la propiedad “Origen de la Fila”.
En este caso, si dominamos el lenguaje SQL podemos construir directamente la SQL que nos devolverá los
valores que mostrará el cuadro combinado, o en caso contrario, usar el “Generador de Consultas” pulsando
en el botón con los 3 puntos de la derecha de esa fila.
En cualquier caso, al final obtendremos esta SQL: SELECT TDatos.Pobl FROM TDatos ORDER BY
TDatos.Pobl;
Aprovechando que tenemos dos cuadros de texto, vamos a ver dos métodos para obtener el valor
“dependiente”, el primero “directamente” en la propiedad “origen del control” del cuadro de texto txtProv, y el
segundo usando código VBA.
Fijaros que al ser un dato de texto, hay que poner las comillas simples antes y después del valor de
cboPobl.
-> Cuadro txtPais: en este caso vamos a obtener el valor por código, una vez que seleccionamos
una población en el cuadro combinado. Para ello, sacamos las propiedades de cboPobl, y nos vamos a la
pestaña Eventos->Después de actualizar. Hacemos clic en el espacio en blanco que hay a su derecha y nos
aparecerá un botón de puntos suspensivos. Hacemos clic sobre ese pequeño botón de puntos suspensivos
y, en la ventana que nos aparece, seleccionamos que queremos generar código. Se nos abrirá el editor de
VB (VBE), con dos líneas por defecto (Private Sub… y End Sub). En medio de esas líneas escribimos el
2
Visítame en http://neckkito.siliconproject.com.ar
siguiente código:
---
Private Sub cboPobl_AfterUpdate()
Me.txtPais=DLookup(“Pais”,”TDatos”,”Pobl=’” &
Me.cboPobl & “’”)
End Sub
---
Pestaña Formato -> Número de Columnas: aquí ponemos 3, en este caso, porque tenemos 3
campos seccionados.
Pestaña Formato -> Ancho de Columnas: aquí ponemos 0cm;0cm;3cm, porque queremos ocultar
las dos primeras columnas (correspondientes a Pais y Prov) y 3cm que será el ancho de la tercera.
Aquí también vamos a ver dos métodos para obtener el valor “dependiente”, el primero
“directamente” en la propiedad “origen del control” del cuadro de texto txtProv, y el segundo usando
código VBA.
=[cboPobl].[column](1)
-> Cuadro txtPais: en este caso vamos a obtener el valor por código, una vez que seleccionamos
una población en el cuadro combinado. Para ello, escribimos el siguiente código:
---
Private Sub cboPobl_AfterUpdate()
Me.txtPais= Me.cboPobl.Column(0)
End Sub
---
Fijaros que Access por defecto, empieza a numerar en 0 en vez de en 1. Así, la columna del país
será la 0, la de la provincia la 1 y la de la población la 2.
3
Visítame en http://neckkito.siliconproject.com.ar
Ahora vamos a ver cómo se haría al trabajar con dos tablas vinculadas.
Columna Dependiente: 1
Número de columnas: 3
Ancho de columnas: 0 cm; 3 cm; 0 cm
Al primer cuadro de texto (txtCCAA1), en “origen de control”, le asignamos la siguiente fórmula:
=DBúsq("Comunidad";"TCCAA";"CodCA=" & Nz([cboProv].[Column](2);0))
En este caso usamos una combinación de la función DBúsq y la propiedad Columna, para buscar
en la tabla TCCAA el nombre de la comunidad que corresponda al CodCA de la provincia seleccionada, que
nos lo da la tercera columna del cuadro combinado. Además, uso la función Nz() para que no aparezca
#Error en [txtCCAA1] al estar en blanco [cboProv]
Al segundo cuadro de texto (txtCCAA2), le asignamos el valor por código, en el evento “Después de
actualizar” del cuadro combinado cboProv, con este código:
---
Private Sub cboProv_AfterUpdate()
End Sub
---
4
Visítame en http://neckkito.siliconproject.com.ar
Ahora, de nuevo, construimos un formulario con los mismos controles que el del ejemplo anterior (o
hacemos un copia-pega de FEjemplo03) y le añadimos otros dos cuadros de texto (txtxCCAA3 y txtCCAA4).
Al cuadro combinado le cambiaremos el Origen de la Fila a este: SELECT CProvCCAA.CodProv,
CProvCCAA.Provincia, CProvCCAA.Comunidad FROM CProvCCAA;
Aquí tiene menos sentido usar la función DBúsq, pues al trabajar sobre la consulta es más sencillo
usar la propiedad Columna, aunque lo vamos a ver igualmente.
· En txtCCAA1, en Origen de Control le ponemos: =DBúsq("Comunidad";"CProvCCAA";"CodProv="
& Nz([cboProv];0))
· A txtCCAA3 y txtCCAA4 se lo asignamos por código, poniendo en Después del actualizar de [cboProv]
lo siguiente:
Me.txtCCAA4 = Me.cboProv.Column(2)
End Sub
UN PAR DE COMENTARIOS
Como podréis apreciar, la opción por código VBA es mucho más rápida que la que trabaja sobre el
origen del control del cuadro de texto, sobre todo si se usa la función DBúsq.
Además, trabajar por código tiene otra ventaja: nos permitiría guardar el valor dependiente en una
tabla, pues le podríamos asignar al cuadro de texto como origen de control el campo de una tabla, cosa que
con la otra opción no es posible, al llevar en dicha propiedad la fórmula para obtener el valor.
Habría otra opción de trabajo con el código VBA, que yo no recomendaría, que consiste en generar
el código no en el cuadro combinado, sino en el propio cuadro de texto, por ejemplo en el evento “Al recibir
el enfoque” o en “Al entrar”.
5
Visítame en http://neckkito.siliconproject.com.ar
Os habréis fijado que uso dos notaciones
distintas para referirme al cuadro combinado
en el Origen de Control: unas veces la larga
([Formularios]![FEjemplo01]![cboPobl]) y otras
la corta ([cboPobl].[column](1)). Ambas son
indistintas.
UN “GRAN” EJEMPLO
Para ver una aplicación “real de todo lo anterior, vamos a
crear un sistema de facturación muy sencillito. Para eso
necesitaremos las siguientes tablas:
· TClientes: con campos IDCliente (Autonumérico y Clave principal), Nombre y NIF (ambos Texto)
· TProductos: con campos IDProd (Autonumérico y Clave), Producto (Texto) y Precio (Moneda)
· TFacturas: con campos IDFact (Autonumérico y Clave), Fecha (Fecha/Hora), Cliente (numérico, que nos
enlazará con IDCliente de TClientes) y TotalFra (Moneda)
· TDetalleFact: con campos ID, Factura (numérico, que enlazará con IDFact), Producto (numérico, que
enlazará con TProductos), Precio (moneda) y Cantidad (numérico)
Rellenamos las tablas TClientes, y TProductos con algunos datos, y nos vamos a centrar en la parte
de facturación. Necesitaremos un Formulario sobre TFacturas y un Subformulario sobre TDetalleFact.
¡Vamos a ello!
Por comodidad, vamos a empezar por el subformulario, al que llamaremos subFDetalleFact. Lo
creamos directamente con el asistente, fijándonos en escoger una distribución tabular. Al finalizar el
asistente, le decimos de abrir en Vista Diseño para hacerle unos pequeños ajustes:
3. Vamos a añadir un cuadro de texto, llamado txtDescripcion, que nos mostrará la descripción del
producto seleccionado, pero sólo a título informativo, pues no interesa guardar ese dato en
TDetalleFact. En su origen de control le ponemos: =[Producto].[Column](1)
Me.Cantidad.SetFocus
End Sub
5. Añadimos otro cuadro de texto, txtSubTot, para ir calculando subtotales, que en este caso será el
[Precio] por la [Cantidad], y así se lo indicamos en su Origen de control: =[Precio]*[Cantidad]
6
Visítame en http://neckkito.siliconproject.com.ar
6. En el pie del formulario, añadimos otro cuadro de texto,
txtSubTotal, que estará oculto, y nos servirá para pasar el Total a la
Factura. En su origen de Control, le ponemos esta fórmula:
=Suma([Precio]*[Cantidad])
'Guardamos el registro
DoCmd.RunCommand acCmdSaveRecord
Me.Recalc
DoCmd.RunCommand acCmdRecordsGoToNew
'Cogemos el valor del cuadro de texto que creamos en el pie del subformulario
vTotal = Me.txtSubTotal.Value
Me.Parent.TotalFra = vTotal
End Sub
Ahora le toca el turno al formulario, que llamaremos FFacturas. Lo creamos con el asistente,
eligiendo en este caso una distribución en columnas, colocamos los 4 campos a nuestro gusto, y le
hacemos los siguientes “retoques”, para dejarlo así de bonito:
7
Visítame en http://neckkito.siliconproject.com.ar
1. El campo Cliente lo convertimos en un cuadro combinado, que mostrará las 3 columnas de
TClientes y almacenará el IDCliente, cosa que logramos con este origen de fila: SELECT
[TClientes].[IdCliente], [TClientes].[NIF], [TClientes].[Nombre] FROM TClientes ORDER BY [NIF]; y
jugando con las propiedades Número de columnas y Ancho de columnas
2. Añadimos dos cuadros de texto independientes (txtNIF y txtNombre) para mostrar los datos del
cliente al seleccionarlo en el cuadro combinado.
3. Añadimos el subformulario creado antes, y relacionamos los campos IDFact del formulario principal
con Factura del subformulario.
4. En este caso, vamos a mostrar la información del cliente por código, por lo que en el evento
“Después de actualizar” del cuadro Cliente, le generamos este código:
Private Sub Cliente_AfterUpdate()
If Nz(Me.Cliente, 0) = 0 Then
Me.txtNIF = Null
Me.txtNombre = Null
Else
Me.txtNIF = Me.Cliente.Column(1)
Me.txtNombre = Me.Cliente.Column(2)
End If
End Sub
5. Para acabar, y para que al cambiar de registro se muestren correctamente los datos del cliente, al
evento “Al activar registro” del Formulario, le hacemos una llamada al evento anterior:
Private Sub Form_Current()
8
Visítame en http://neckkito.siliconproject.com.ar
Call Cliente_AfterUpdate
End Sub
Y esto es todo, que no es poco. Espero que os sirva para vuestras aplicaciones.
9
Visítame en http://neckkito.siliconproject.com.ar