miércoles, 25 de febrero de 2015

Usando dos o más tablas en un Formulario agregar un Combobox y que este ponga datos sincronizados a más controles

Con esto lo que pretendo es que conozcan algunas formas diferentes de llegar al mismo resultado, todo lo expuesto aquí esta tomado de ejemplos, no trato de explicar cada método, si tiene duda en algún método consulte la ayuda de access. Debo agradecer a Patxi Sanz y a Juan M. Afán, por colaborar y sugerir otros métodos y ayudar a hacer los ejemplos.
Existen varias formas de hacerlo vamos a ver 5 de ellas con sus variantes:
1.- Con el asistente y todo en automático
2.- Con el asistente y después agregando el combo pero en automático
3.- Con el asistente y después agregando el combo y lo demás de forma manual con Column
            a) Sin usar eventos
            b) Usando eventos para no poner formula en origen del control
4.- Con el asistente y después agregando el combo y lo demás de forma  manual con DBusqueda
a) Sin usar eventos
            b) Usando eventos para no poner formula en origen del control
5.- Con el Asistente y después con Recordset
            a) Con DAO
            b) Con ADO
            c) Con Recordset directo en el Combo
            d) Con DAO directo en el Combo
            d) Con ADO directo en el Combo

1.- Con el Asistente y todo en Automático

Que te parece hacer una práctica pequeña que se paresca a esto: 


Creamos una tabla por decir Clientes
Con campos
IdCliente – Autonumérico – Campo clave principal
Nombre – Texto
Domicilio – Texto
Ciudad – texto
Etc..

Otra tabla Factura
IdFactura – Autonumérico – Campo clave principal
IdCliente – Asistente de búsqueda – En una tabla – Tabla Cliente – IdCliente
y   Nombre y siguiente hasta terminar
Fecha – Facha/hora
Etc.

Agrega unos nombres a la tabla Clientes
Con el asistente Creamos un Formulario:
Seleccionas la tabla Clientes, agregas todos menos el campo de Nombre
Seleccionas la tabla Factura, agregas todos los campos

Te pregunta como deseas ver los datos por Cliente o por Factura seleccionas por Factura y te pone un único Formulario, le das siguiente hasta que terminas.

Y listo tenemos mas o menos esto:



2.- Con el asistente y después agregando el combo pero en Automático

Vamos a utilizar el mismo ejemplo la tabla tblCliente y la tabla tblFactura (en el ejemplo es tblCliente y tblFactura)

Te metes a relaciones seleccionas la línea que une a una y otra y le das borrar (Supr), guardas la nueva relación, te vas a la tabla tblFacturas y borras IDClientes.

Y vuelves a crearlo pero ahora solo
IDClientes – número – entero largo y guardas
Te vas a relaciones y creas la relación de la tabla tblClientes IDClientes a la tabla tblFacturas IDClientes y le puedes dar integridad referencial (La integridad referencial se refiere a un conjunto de normas que nos aseguran que los datos se mantendrán correctamente relacionados una vez establecida la relación y de que no se podrán eliminar datos accidentalmente), guardamos.
Con el asistente Creamos un nuevo Formulario:
Seleccionas la tabla tblClientes, agregas todos los campos.
Seleccionas la tabla tblFactura, agregas todos los campos.


Te pregunta como deseas ver los datos por Cliente o por Factura seleccionas por Factura y te pone un único Formulario, le das siguiente hasta que terminas.
Observas la diferencia el control de IdCliente no es cuadro combinado, lo tenemos que crear nosotros, pero también fíjate si tienes datos que si cambiamos IdCliente por otro numero en automático cambia el Nombre, Domicilio, Ciudad.
En el nuevo formulario en vista diseño agregamos con el asistente un cuadro combinado y salen dos opciones escogemos la primera: Deseo que el cuadro combinado busque los valores en una tabla o consulta, damos siguiente y seleccionamos la tabla tblClientes y agregamos todos los campos que usemos en este caso todos, siguiente hasta terminar.

Siguiendo en vista diseño, en el combo en propiedades en origen del registro seleccionamos IdCliente de la factura y podemos borrar los cuadros de texto: IdCliente Nombre y IdCliente, guardamos y podemos probar como quedo.

3a.- Con el asistente y después agregando el combo y lo demás de forma manual con Column (Sin usar eventos)

Vamos a utilizar el mismo ejemplo la tabla tblClientes y la tabla tblFactura

La tabla tblClientes igual
Y la tabla tblFactura
IDClientes – número – entero largo
Te vas a relaciones y creas la relación de la tabla tblClientes IDClientes a la tabla tblFacturas IDClientes y le puedes dar integridad referencial (La integridad referencial se refiere a un conjunto de normas que nos aseguran que los datos se mantendrán correctamente relacionados una vez establecida la relación y de que no se podrán eliminar datos accidentalmente), guardamos.
Con el asistente Creamos un nuevo Formulario:
Seleccionas la tabla Clientes, agregas solo el campo IdCliente
Seleccionas la tabla Factura, agregas todos los campos

Te pregunta como deseas ver los datos por Cliente o por Factura seleccionas
por Factura y te pone un único Formulario, le das siguiente hasta que terminas.

En vista Diseño vamos a crear un Cuadro combinado para el nombre, con ayuda del asistente  salen dos opciones escogemos la primera: Deseo que el cuadro combinado busque los valores en una tabla o consulta, damos siguiente y seleccionamos la tabla tblClientes y agregamos los campos que usemos en este caso todos, siguiente hasta donde dice almacenar el valor en el campo: buscamos IDCliente de la Factura y siguiente hasta finalizar. En propiedades del cuadro combinado en nombre lo cambiamos a: CboNombre
Agregamos 2 cuadro de texto, en propiedades ponemos:
Propiedades:              Nombre          Origen del control
cuadro de texto1        txtDomicilio   = CboNombre.column(2)
cuadro de texto2        txtCiudad        = CboNombre.column(3)

3b.- Con el asistente y después agregando el combo y lo demás de forma manual con Column (Usando eventos)

Vamos a utilizar el mismo ejemplo la tabla tblClientes y la tabla tblFactura

La tabla Clientes igual
IDClientes – número – entero largo
Te vas a relaciones y creas la relación de la tabla tblClientes IDClientes a la tabla tblFacturas IDClientes y le puedes dar integridad referencial (La integridad referencial se refiere a un conjunto de normas que nos aseguran que los datos se mantendrán correctamente relacionados una vez establecida la relación y de que no se podrán eliminar datos accidentalmente), guardamos.
Con el asistente Creamos un nuevo Formulario:
Seleccionas la tabla tblClientes, agregas solo el campo IdCliente
Seleccionas la tabla tblFactura, agregas todos los campos

Te pregunta como deseas ver los datos por Cliente o por Factura seleccionas por Factura y te pone un único Formulario, le das siguiente hasta que terminas.
En vista Diseño vamos a crear un Cuadro combinado para el nombre, con ayuda del asistente  salen dos opciones escogemos la primera: Deseo que el cuadro combinado busque los valores en una tabla o consulta, damos siguiente y seleccionamos la tabla tblClientes y agregamos los campos que usemos en este caso todos, siguiente hasta donde dice almacenar el valor en el campo: buscamos IDCliente de la Factura y siguiente hasta finalizar. En propiedades del cuadro combinado en nombre lo cambiamos a: CboNombre
En vista diseño agregamos 2 cuadros de texto, en propiedades ponemos:
Propiedades:              Nombre         
cuadro de texto1        txtDomicilio  
cuadro de texto2        txtCiudad       
Seleccionamos el combobox, nos vamos a propiedades en eventos buscamos el que dice después de actualizar y le damos a los tres puntos, luego generador de código y aceptar. Entramos a VBA y escribimos:
Private Sub CboNombre _AfterUpdate()
txtDomicilio = CboNombre.Column(2)
txtCiudad = CboNombre.Column(3)
End Sub
Probamos, observamos que efectivamente cuando abrimos el combo y seleccionamos un nombre el domicilio y la ciudad se ponen bien, pero si cambiamos de registro o al abrir no funciona, debemos de arreglarlo. Claro que si por alguna causa los cuadros de texto independientes, (txtDomicilio), (txtCiudad), etc., requerimos que sea dependientes por ejemplo supongamos que el combo nos trae el nombre del producto y requerimos guardar el precio unitario que vamos a dar por aquello que cambie de precio y nos modifique las facturas anteriores. Entonces si el cuadro de texto es dependiente, es decir guardamos su información en origen del registro no requerimos lo siguiente pues nos va a dar los datos correctos.
En vista diseño, propiedades del formulario nos vamos a eventos al activar registro, a los tres puntos, generador de código y aceptamos, ponemos:
Private Sub Form_Current()
txtDomicilio = CboNombre.Column(2)
txtCiudad = CboNombre.Column(3)
End Sub
Como podemos observar estamos repitiendo el código para evitar escribir dos veces podemos usar una de estas formas:
Private Sub Form_Current()
Call CboNombre _AfterUpdate        ‘O  sin Call solo CboNombre _AfterUpdate
End Sub
O Creamos un  método auxiliar
Private Sub CargaDatos()
txtDomicilio = CboNombre.Column(2)
txtCiudad = CboNombre.Column(3)
End Sub
Y lo llamamos desde los dos eventos
Private Sub CboNombre _AfterUpdate()
Call CargaDatos

End Sub
Private Sub Form_Current()
Call CargaDatos
End Sub
En todos los demás ejemplos vamos a usar la primera forma.

4a.- Con el asistente y después agregando el combo, lo demás de forma  manual con DBusqueda (Sin eventos)
Vamos a utilizar el mismo ejemplo la tabla tblClientes y la tabla tblFactura

La tabla tblClientes igual
La tabla tblFactura
IDClientes – número – entero largo
Te vas a relaciones y creas la relación de la tabla tblClientes IDClientes a la tabla tblFacturas IDClientes y le puedes dar integridad referencial (La integridad referencial se refiere a un conjunto de normas que nos aseguran que los datos se mantendrán correctamente relacionados una vez establecida la relación y de que no se podrán eliminar datos accidentalmente), guardamos.
Con el asistente Creamos un nuevo Formulario:
Seleccionas la tabla tblClientes, agregas solo el campo IdCliente
Seleccionas la tabla tblFactura, agregas todos los campos
Te pregunta como deseas ver los datos por Cliente o por Factura seleccionas por Factura y te pone un único Formulario, le das siguiente hasta que terminas.
En vista Diseño vamos a crear un Cuadro combinado para el nombre, con ayuda del asistente  salen dos opciones escogemos la primera: Deseo que el cuadro combinado busque los valores en una tabla o consulta, damos siguiente y seleccionamos la tabla tblClientes y agregamos los campos que usemos en este caso IDCliente y Nombre, siguiente hasta donde dice almacenar el valor en el campo: buscamos IDCliente de la Factura y siguiente hasta finalizar. En propiedades del cuadro combinado en nombre lo cambiamos a: CboNombre
Agregamos 2 cuadro de texto, en propiedades ponemos:
Propiedades:              Nombre          Origen del control
cuadro de texto1   txtDomicilio           =DBúsq("Domicilio","tblCliente","IDCliente = " & [CboNombre])
cuadro de texto2   txtCiudad          =DBúsq("Ciudad","tblCliente","IDCliente = " & [CboNombre])
Observemos que si tenemos datos en el formulario los muestra bien pero si nos vamos a un registro nuevo, todos nuestros campos independientes nos sale con #Error, muy bien esto ocurre por que nuestro combo CboNombre no tiene ningún registro (esta en blanco).
Para corregirlo vamos a usar primero la función Nz para convertir el nulo en 0 y después la función if para decirle que si es Nulo=0 lo deje en blanco y si no es nulo que haga la búsqueda y esto quedaría así:
Nombre          Origen del control
txtDomicilio            =SiInm(Nz([CboNombre],0)=0," ",DBúsq("Domicilio","tblCliente","IDCliente = " & [CboNombre]))
txtCiudad                              =SiInm(Nz([CboNombre],0)=0," ",DBúsq("Ciudad","tblCliente","IDCliente = " & [CboNombre]))
4b.- Con el asistente y después agregando el combo, lo demás de forma  manual con DBusqueda (Con eventos)
Vamos a utilizar el mismo ejemplo la tabla tblClientes y la tabla tblFactura

La tabla tblClientes igual
La tabla tblFactura
IDClientes – número – entero largo
Te vas a relaciones y creas la relación de la tabla tblClientes IDClientes a la tabla tblFacturas IDClientes y le puedes dar integridad referencial (La integridad referencial se refiere a un conjunto de normas que nos aseguran que los datos se mantendrán correctamente relacionados una vez establecida la relación y de que no se podrán eliminar datos accidentalmente), guardamos.
Con el asistente Creamos un nuevo Formulario:
Seleccionas la tabla Clientes, agregas solo el campo IdCliente
Seleccionas la tabla Factura, agregas todos los campos
Te pregunta como deseas ver los datos por Cliente o por Factura seleccionas por Factura y te pone un único Formulario, le das siguiente hasta que terminas.
En vista Diseño vamos a crear un Cuadro combinado para el nombre, con ayuda del asistente  salen dos opciones escogemos la primera: Deseo que el cuadro combinado busque los valores en una tabla o consulta, damos siguiente y seleccionamos la tabla tblClientes y agregamos los campos que usemos en este caso solo IDCliente y Nombre, siguiente hasta donde dice almacenar el valor en el campo: buscamos IDCliente de la Factura y siguiente hasta finalizar. En propiedades del cuadro combinado en nombre lo cambiamos a: CboNombre
Agregamos 2 cuadros de texto independiente, en propiedades ponemos:
Propiedades:              Nombre
cuadro de texto1  txtDomicilio          
cuadro de texto2  txtCiudad
Seleccionamos el combobox, nos vamos a propiedades en eventos buscamos el que dice después de actualizar y le damos a los tres puntos, luego generador de código y aceptar. Entramos a VBA y escribimos:
Private Sub CboNombre _AfterUpdate()
txtDomicilio = DLookup ("Domicilio","tblCliente","IDCliente = " &  Me.CboNombre)
txtCiudad = DLookup ("Ciudad","tblCliente","IDCliente = " & Me.CboNombre)
End Sub
Probamos, observamos que efectivamente cuando abrimos el combo y seleccionamos un nombre el domicilio y la ciudad se ponen bien, pero si cambiamos de registro o al abrir no funciona, debemos de arreglarlo. Claro que si por alguna causa el cuadro de texto independiente, (txtDomicilio) requerimos que sea dependiente por ejemplo supongamos que el combo nos trae el nombre del producto y requerimos guardar el precio unitario que vamos a dar por aquello que cambie de precio y nos modifique las facturas anteriores. Entonces si el cuadro de texto es dependiente, es decir guardamos su información en origen del registro no requerimos lo siguiente pues nos va a dar los datos correctos.
En vista diseño, propiedades del formulario nos vamos a eventos al activar registro, a los tres puntos, generador de código y aceptamos, ponemos:
Private Sub Form_Current()
Call CboNombre _AfterUpdate
End Sub
Volvemos a revisar y efectivamente cuando cambiamos de registro funciona correcto, pero al ir a un nuevo registro se genera un error, el control CboNombre es un valor nulo y debemos volver a corregirlo diciéndole que si el control CboNombre es nulo que los controles independientes los deje en blanco y si no que realice la búsqueda así:
Private Sub Form_Current()
If IsNull(CboNombre) Then
txtDomicilio = " "
txtCiudad = " "
Else
Call CboNombre _AfterUpdate
End If
End Sub
Revisamos y listo, funciona todo bien.
5a.- Con el Asistente y después con Recordset con DAO
Vamos a utilizar el mismo ejemplo la tabla tblClientes y la tabla tblFactura

La tabla tblClientes igual
La tabla tblFactura
IDClientes – número – entero largo
Te vas a relaciones y creas la relación de la tabla tblClientes IDClientes a la tabla tblFacturas IDClientes y le puedes dar integridad referencial (La integridad referencial se refiere a un conjunto de normas que nos aseguran que los datos se mantendrán correctamente relacionados una vez establecida la relación y de que no se podrán eliminar datos accidentalmente), guardamos.
Con el asistente Creamos un nuevo Formulario:
Seleccionas la tabla tblClientes, agregas solo el campo IdCliente
Seleccionas la tabla tblFactura, agregas todos los campos
Te pregunta como deseas ver los datos por Cliente o por Factura seleccionas por Factura y te pone un único Formulario, le das siguiente hasta que terminas.
En vista Diseño vamos a crear un Cuadro combinado para el nombre, con ayuda del asistente  salen dos opciones escogemos la primera: Deseo que el cuadro combinado busque los valores en una tabla o consulta, damos siguiente y seleccionamos la tabla tblClientes y agregamos los campos que usemos en este caso solo IDCliente y Nombre, siguiente hasta donde dice almacenar el valor en el campo: buscamos IDCliente de la Factura y siguiente hasta finalizar. En propiedades del cuadro combinado en nombre lo cambiamos a: CboNombre
Agregamos 2 cuadros de texto independiente, en propiedades ponemos:
Propiedades:              Nombre
cuadro de texto1  txtDomicilio          
cuadro de texto2  txtCiudad
Seleccionamos el combobox, nos vamos a propiedades en eventos buscamos el que dice después de actualizar y le damos a los tres puntos, luego generador de código y aceptar. Entramos a VBA y escribimos:
Private Sub CboNombre_AfterUpdate()
Dim db As DAO.Database
    Dim rs As DAO.Recordset
    Dim strSQL As String

    CboNombre.SetFocus
    If CboNombre.Value > 0 Then
        strSQL = "SELECT * FROM tblCliente WHERE IDcliente = " & CboNombre.Value
   
        Set db = CurrentDb
        Set rs = db.OpenRecordset(strSQL)
        If Not rs.BOF Then
            Me.txtDomicilio = rs("Domicilio")
            Me.txtCiudad = rs("Ciudad")
        End If
        rs.Close
        Set rs = Nothing
        db.Close
        Set db = Nothing
    End If   
End Sub
Probamos, observamos que efectivamente cuando abrimos el combo y seleccionamos un nombre el domicilio y la ciudad se ponen bien, pero si cambiamos de registro o al abrir no funciona, debemos de arreglarlo. En vista diseño, propiedades del formulario nos vamos a eventos al activar registro, a los tres puntos, generador de código y aceptamos, ponemos Call CboNombre _AfterUpdate
Volvemos a revisar y efectivamente cuando cambiamos de registro funciona correcto, pero al ir a un nuevo registro se genera un error, se queda el último valor que tuvimos, debemos volver a corregirlo diciéndole que si el control CboNombre es nulo que los controles independientes los deje en blanco y si no que realice la búsqueda así:
Private Sub Form_Current()
If IsNull(CboNombre) Then
txtDomicilio = " "
txtCiudad = " "
Else
Call CboNombre _AfterUpdate
    End If
End Sub

5b.- Con el Asistente y después con Recordset con ADO
Vamos a utilizar el mismo ejemplo la tabla tblClientes y la tabla tblFactura

La tabla tblClientes igual
La tabla tblFactura
IDClientes – número – entero largo
Te vas a relaciones y creas la relación de la tabla tblClientes IDClientes a la tabla tblFacturas IDClientes y le puedes dar integridad referencial (La integridad referencial se refiere a un conjunto de normas que nos aseguran que los datos se mantendrán correctamente relacionados una vez establecida la relación y de que no se podrán eliminar datos accidentalmente), guardamos.
Con el asistente Creamos un nuevo Formulario:
Seleccionas la tabla tblClientes, agregas solo el campo IdCliente
Seleccionas la tabla tblFactura, agregas todos los campos
Te pregunta como deseas ver los datos por Cliente o por Factura seleccionas
por Factura y te pone un único Formulario, le das siguiente hasta que
terminas.

En vista Diseño vamos a crear un Cuadro combinado para el nombre, con ayuda del asistente  salen dos opciones escogemos la primera: Deseo que el cuadro combinado busque los valores en una tabla o consulta, damos siguiente y seleccionamos la tabla tblClientes y agregamos los campos que usemos en este caso solo IDCliente y Nombre, siguiente hasta donde dice almacenar el valor en el campo: buscamos IDCliente de la Factura y siguiente hasta finalizar. En propiedades del cuadro combinado en nombre lo cambiamos a: CboNombre
Agregamos 2 cuadros de texto independiente, en propiedades ponemos:
Propiedades:              Nombre
cuadro de texto1  txtDomicilio          
cuadro de texto2  txtCiudad
Seleccionamos el combobox, nos vamos a propiedades en eventos buscamos el que dice después de actualizar y le damos a los tres puntos, luego generador de código y aceptar. Entramos a VBA y escribimos:
Private Sub CboNombre_AfterUpdate()
Dim rs As ADODB.Recordset
    Dim strSQL As String
   
    CboNombre.SetFocus
    If CboNombre.Value > 0 Then
        strSQL = "SELECT * FROM tblCliente WHERE IDCliente = " & CboNombre.Value
   
        Set rs = CreateObject("ADODB.Recordset")
        rs.CursorType = adOpenKeyset
        rs.LockType = adLockOptimistic
        rs.Open strSQL, CurrentProject.Connection
       
        If rs.State = 1 Then
            If Not rs.BOF Then
                Me.txtDomicilio = rs("Domicilio")
                Me.txtCiudad = rs("Ciudad")
            End If
            rs.Close
        End If
        Set rs = Nothing
    End If
   
End Sub
Probamos, observamos que efectivamente cuando abrimos el combo y seleccionamos un nombre el domicilio y la ciudad se ponen bien, pero si cambiamos de registro o al abrir no funciona, debemos de arreglarlo. En vista diseño, propiedades del formulario nos vamos a eventos al activar registro, a los tres puntos, generador de código y aceptamos, ponemos Call CboNombre _AfterUpdate
Volvemos a revisar y efectivamente cuando cambiamos de registro funciona correcto, pero al ir a un nuevo registro se genera un error, se queda el último valor que tuvimos, debemos volver a corregirlo diciéndole que si el control CboNombre es nulo que los controles independientes los deje en blanco y si no que realice la búsqueda así:
Private Sub Form_Current()
If IsNull(CboNombre) Then
txtDomicilio = " "
txtCiudad = " "
Else
Call CboNombre _AfterUpdate
End If
End Sub

Y listo debe de funcionar.

5c.- Con el Asistente y después con Recordset directo en el Combo
Vamos a utilizar el mismo ejemplo la tabla tblClientes y la tabla tblFactura

La tabla tblClientes igual
La tabla tblFactura
IDClientes – número – entero largo
Te vas a relaciones y creas la relación de la tabla tblClientes IDClientes a la tabla tblFacturas IDClientes y le puedes dar integridad referencial (La integridad referencial se refiere a un conjunto de normas que nos aseguran que los datos se mantendrán correctamente relacionados una vez establecida la relación y de que no se podrán eliminar datos accidentalmente), guardamos.
Con el asistente Creamos un nuevo Formulario:
Seleccionas la tabla tblClientes, agregas solo el campo IdCliente
Seleccionas la tabla tblFactura, agregas todos los campos

Te pregunta como deseas ver los datos por Cliente o por Factura seleccionas por Factura y te pone un único Formulario, le das siguiente hasta que terminas.
En vista Diseño vamos a crear un Cuadro combinado para el nombre, con ayuda del asistente  salen dos opciones escogemos la primera: Deseo que el cuadro combinado busque los valores en una tabla o consulta, damos siguiente y seleccionamos la tabla tblClientes y agregamos los campos que usemos en este caso todos, siguiente hasta donde dice almacenar el valor en el campo: buscamos IDCliente de la Factura y siguiente hasta finalizar. En propiedades del cuadro combinado en nombre lo cambiamos a: CboNombre
Agregamos 2 cuadros de texto independiente, en propiedades ponemos:
Propiedades:              Nombre
cuadro de texto1  txtDomicilio          
cuadro de texto2  txtCiudad
Seleccionamos el combobox, nos vamos a propiedades en eventos buscamos el que dice después de actualizar y le damos a los tres puntos, luego generador de código y aceptar. Entramos a VBA y escribimos:
Private Sub CboNombre_AfterUpdate()
     Me.txtDomicilio = Me.CboNombre.Recordset.Fields!Domicilio
     Me.txtCiudad = Me.CboNombre.Recordset.Fields!Ciudad
End Sub
Probamos, observamos que efectivamente cuando abrimos el combo y seleccionamos un nombre el domicilio y la ciudad se ponen bien, pero si cambiamos de registro o al abrir no funciona, debemos de arreglarlo. En vista diseño, propiedades del formulario nos vamos a eventos al activar registro, a los tres puntos, generador de código y aceptamos, ponemos Call CboNombre _AfterUpdate
Si abrimos el formulario nos damos cuenta que nos sale un error (error 91 en tiempo de ejecución). Vamos a arreglarlo, le damos depurar.
Access no puede determinar por si solo qué elemento está seleccionado en el combo pero nosotros si podemos saberlo con la propiedad ListIndex y que revise, si es nulo que los controles independientes los deje en blanco y si no que realice la búsqueda así:
Private Sub Form_Current()
     If Me.CboNombre.ListIndex < 0 Then
     Me.txtCiudad = " "
     Me.txtDomicilio = " "
     Else
     CboNombre_AfterUpdate
     End If
End Sub

5d.- Con el Asistente y después con DAO directo en el Combo
Vamos a utilizar el mismo ejemplo la tabla tblClientes y la tabla tblFactura

La tabla tblClientes igual
La tabla tblFactura
IDClientes – número – entero largo
Te vas a relaciones y creas la relación de la tabla tblClientes IDClientes a la tabla tblFacturas IDClientes y le puedes dar integridad referencial (La integridad referencial se refiere a un conjunto de normas que nos aseguran que los datos se mantendrán correctamente relacionados una vez establecida la relación y de que no se podrán eliminar datos accidentalmente), guardamos.
Con el asistente Creamos un nuevo Formulario:
Seleccionas la tabla tblClientes, agregas solo el campo IdCliente
Seleccionas la tabla tblFactura, agregas todos los campos
Te pregunta como deseas ver los datos por Cliente o por Factura seleccionas por Factura y te pone un único Formulario, le das siguiente hasta que terminas.
En vista Diseño vamos a crear un Cuadro combinado para el nombre, con ayuda del asistente  salen dos opciones escogemos la primera: Deseo que el cuadro combinado busque los valores en una tabla o consulta, damos siguiente y seleccionamos la tabla tblClientes y agregamos los campos que usemos en este caso todos, siguiente hasta donde dice almacenar el valor en el campo: buscamos IDCliente de la Factura y siguiente hasta finalizar. En propiedades del cuadro combinado en nombre lo cambiamos a: CboNombre
Copiamos el origen de la fila a word y lo borramos del origen de la fila:
SELECT tblCliente.IDCliente, tblCliente.Cliente, tblCliente.Domicilio, tblCliente.Ciudad, tblCliente.Estado, tblCliente.CP, tblCliente.Teléfono FROM tblCliente;
Y la podemos simplificar así: (Solo quitamos la tabla a cada campo)
Select IDCliente, Cliente, Domicilio, Ciudad, Estado, CP, Teléfono FROM tblCliente;
Tenemos que cargar el combo y declarar la variable nos vamos al evento al cargar del formulario y ponemos primero arriba de el:
Option Compare Database
Option Explicit
'Sentencia para cargar el combo (Observa que solo le agregamos lo que esta en rojo de la de Word)
Private Const psSql As String = "Select IDCliente, Cliente, Domicilio, Ciudad, Estado, CP, Teléfono FROM tblCliente;"
'Declaramos las variables para que sea DAO
Dim rstdao As dao.Recordset
Private Sub Form_Load()
'Al cargar el formulario asignamos el recordset de DAO del combo
Set rstdao = CurrentDb.OpenRecordset(psSql, dbOpenSnapshot, dbReadOnly)
Set Me.CboNombre.Recordset = rstdao
End Sub
Y creamos otro evento ahora al decargar del formulario (Para liberar memoria y limpiar en caso de errores):
Private Sub Form_Unload(Cancel As Integer)
On Error Resume Next
'Cerramos el recordset y liberamos memoria

rstdao.Close
Set rstdao = Nothing
If Err <> 0 Then
Err.Clear
On Error GoTo 0
End If
End Sub
Ahora vamos a hacer que el combo funcione, en después de actualizar primero recorremos el recordset y después asignamos los valores.
Private Sub CboNombre_AfterUpdate()
Me.CboNombre.Recordset.MoveFirst
Me.CboNombre.Recordset.Move Me.CboNombre.ListIndex
'Asignamos los valores
Me.txtDomicilio = Me.CboNombre.Recordset!Domicilio
Me.txtCiudad = Me.CboNombre.Recordset!Ciudad
End Sub
Probamos, observamos que efectivamente cuando abrimos el combo y seleccionamos un nombre el domicilio y la ciudad se ponen bien, pero si cambiamos de registro o al abrir no funciona, debemos de arreglarlo. En vista diseño, propiedades del formulario nos vamos a eventos al activar registro, a los tres puntos, generador de código y aceptamos, ponemos Call CboNombre _AfterUpdate
Volvemos a probar y vemos que si funciona pero cuando vamos a un registro nuevo marca un error por los nulos, lo arreglamos:
Private Sub Form_Current()
If IsNull(CboNombre) Then
txtDomicilio = " "
txtCiudad = " "
Else
CboNombre_AfterUpdate
End If
End Sub
Y listo funciona y no marca ninguna falla.

5e.- Con el Asistente y después con ADO directo en el Combo
Vamos a utilizar el mismo ejemplo la tabla tblClientes y la tabla tblFactura

La tabla tblClientes igual
La tabla tblFactura
IDClientes – número – entero largo
Te vas a relaciones y creas la relación de la tabla tblClientes IDClientes a la tabla tblFacturas IDClientes y le puedes dar integridad referencial (La integridad referencial se refiere a un conjunto de normas que nos aseguran que los datos se mantendrán correctamente relacionados una vez establecida la relación y de que no se podrán eliminar datos accidentalmente), guardamos.
Con el asistente Creamos un nuevo Formulario:
Seleccionas la tabla tblClientes, agregas solo el campo IdCliente
Seleccionas la tabla tblFactura, agregas todos los campos

Te pregunta como deseas ver los datos por Cliente o por Factura seleccionas por Factura y te pone un único Formulario, le das siguiente hasta que terminas.
En vista Diseño vamos a crear un Cuadro combinado para el nombre, con ayuda del asistente  salen dos opciones escogemos la primera: Deseo que el cuadro combinado busque los valores en una tabla o consulta, damos siguiente y seleccionamos la tabla tblClientes y agregamos los campos que usemos en este caso todos, siguiente hasta donde dice almacenar el valor en el campo: buscamos IDCliente de la Factura y siguiente hasta finalizar. En propiedades del cuadro combinado en nombre lo cambiamos a: CboNombre
Copiamos el origen de la fila a word y lo borramos del origen de la fila:
SELECT tblCliente.IDCliente, tblCliente.Cliente, tblCliente.Domicilio, tblCliente.Ciudad, tblCliente.Estado, tblCliente.CP, tblCliente.Teléfono FROM tblCliente;
Y la podemos simplificar así: (Solo quitamos la tabla a cada campo)
Select IDCliente, Cliente, Domicilio, Ciudad, Estado, CP, Teléfono FROM tblCliente;
Tenemos que cargar el combo y declarar la variable nos vamos al evento al cargar del formulario y ponemos primero arriba de el:
Option Compare Database
Option Explicit
'Sentencia para cargar el combo (Observa que solo le agregamos lo que esta en rojo de la de Word)
Private Const psSql As String = "Select IDCliente, Cliente, Domicilio, Ciudad, Estado, CP, Teléfono FROM tblCliente;"
'Declaramos las variables para que sea ADO
Dim rstAdo As ADODB.Recordset
Private Sub Form_Load()
'Al cargar el formulario asignamos el recordset de ADO del combo
Set rstAdo = New ADODB.Recordset
rstAdo.CursorLocation = adUseClient         ‘Para no tener problemas con la posición ‘del combo le asignamos el lado del cliente
rstAdo.Open psSql, CurrentProject.Connection, adOpenStatic, adLockReadOnly
Set Me.CboNombre.Recordset = rstAdo
End Sub
Y creamos otro evento ahora al decargar del formulario (Para liberar memoria y limpiar en caso de errores):
Private Sub Form_Unload(Cancel As Integer)
On Error Resume Next
'Cerramos el recordset y liberamos memoria

rstdao.Close
Set rstdao = Nothing
If Err <> 0 Then
Err.Clear
On Error GoTo 0
End If
End Sub
Ahora vamos a hacer que el combo funcione, en después de actualizar primero recorremos el recordset y después asignamos los valores.
Private Sub CboNombre_AfterUpdate()
Me.CboNombre.Recordset.MoveFirst
Me.CboNombre.Recordset.Move Me.CboNombre.ListIndex
'Asignamos los valores
Me.txtDomicilio = Me.CboNombre.Recordset!Domicilio
Me.txtCiudad = Me.CboNombre.Recordset!Ciudad
End Sub
Probamos, observamos que efectivamente cuando abrimos el combo y seleccionamos un nombre el domicilio y la ciudad se ponen bien, pero si cambiamos de registro o al abrir no funciona, debemos de arreglarlo. En vista diseño, propiedades del formulario nos vamos a eventos al activar registro, a los tres puntos, generador de código y aceptamos, ponemos Call CboNombre _AfterUpdate
Volvemos a probar y vemos que si funciona pero cuando vamos a un registro nuevo marca un error por los nulos, lo arreglamos:
Private Sub Form_Current()
If IsNull(CboNombre) Then
txtDomicilio = " "
txtCiudad = " "
Else
CboNombre_AfterUpdate
End If
End Sub

Les dejo el archivo con todos los métodos.
https://www.dropbox.com/s/ded7r9cz6qldp5e/FormasCombos.mdb?dl=0


2 comentarios:

  1. AYUDAAAA! Me ha puesto el error #¿Nombre? en los campos Nombre... domicilio...
    ¿Cómo puedo corregirlo?

    ResponderBorrar