Refrescar o actualizar combo desde formulario modo dialogo
Tengo un combo "domicilio" en un formulario principal que despliega 4 columnas con los datos completos de la vivienda -id oculto, calle, nro, dto, localidad- las cuales se muestran automaticamente en cuadros de texto contiguos una vez seleccionada la opción de la lista. El dato que queda en el campo con la flecha es el nombre de la calle. A su vez, en ese campo si realizo un doble click me abre el formulario donde se cargan los datos completos de vivienda que entre otros están los que forman las columnas antes mencionadas. Cuando abro ese formulario, que se muestra en modo dialogo, y cambio alguno de los datos que están en los cuadros de texto no hay problema y se actualizan al instante en la vista del formulario principal; pero cuando quiero cambiar el nombre de una calle no actualiza inmediatamente sino cuando en formulario principal voy a siguiente registro y vuelvo hacia atrás. ¿Cómo podría producir ese cambio del nombre de calle en formulario principal desde el formulario abierto en modo dialogo donde se cargan los datos del combo domicilio? PD: si ese formulario lo abro en modo normal el cambio o la actualización sí se realiza.
2 Respuestas
Es correcto como le responden, no obstante, le recomiendo hacerlo con SQL, toda vez, que cuando trabaje con formularios independientes todo cambia, no tendrá la opción del Requery, en este caso tendrá que volver actualizar con SQL el origen de datos.
A nivel ilustrativo utilizo bases de datos en la nube con Access y PostgreSQL, manipulo la base de datos todo con ADODB, para llenar formularios, cuadros combinados y cuadros de lista lo hago con recordset desconectados. En este video explico un CRUD con tablas en Access y con formularios independientes observe como lleno los cuadros combinados CRUD CON ADO Y MODULOS DE CLASE EN ACCESS. PARTE 2 - VIDEO # 3 - (youtube.com) de pronto lo ve difícil, pero el trabajo ya está hecho basta con saber usar el módulo de clase.
- Compartir respuesta
Lo normal es qiue los combos se llenen de datos al abrir el formulario y con la excepción de que se cambie su contenido en tiempo de ejecución (por ejemplo cuando se crean combos 'en cascada') su contenido permanece inalterado.
Access `provee un comando que (recarga/actualiza) el contenido a voluntad del programador, es 'Requery'
Si el objeto [calle] pertenece al formulario activo :
Me. Calle. Requery
En lugar de 'Me', se utilizará la ruta adecuada sea relativa o absoluta.
(Un subformulario: Me.[nombre-subformulario].Form.[calle].Requery )
(Un formulario abierto e independiente: Forms.[nombre-formulario].[calle].Requery)
Con Me. Requery se recarga (símil a abrirlo y cerrarlo) el formulario activo.
Gracias. Este caso sería un formulario abierto en modo dialogo [F_vivienda_activa] donde se generan las correcciones del formulario activo principal [F_ALUMNOS]. El código sugerido lo coloqué en evento "despues de actualizar" del combo calle del [F_vivienda_activa] y debiera hacer referencia al combo de formulario principal donde esta la calle ("vivienda" es en realidad ese combo, contiene nombre de calle, nro, dto, localidad), pero me está tirando error así. ¿Dónde debiera escribir el código? también probé en "al cerrar" del formulario [F_vivienda_activa]
Forms.[F_ALUMNOS].[vivenda].Requery
PD: ¿tiene que ver que el formulario F_vivienda_activa se abre en modo dialogo? si lo hago abrir en modo normal las correcciones impactan en formulario F_ALUMNOS con sólo colocar macro actualizar registro en al cerrar formulario.
Se pueden dar varios casos, en el que aquí se trata, se puede hacer todo en el formulario modal (que un formulario sea modal solo implica que no puede perder el foco ni la acción).
Si se va a modificar los datos, hay que acordar que son compartidos, por lo que hay que guardar las modificaciones 'antes' de actualizar el formulario subyacente, en otro caso (no guardarlos esperando que lo haga de forma automática al cerrarlo) no habría cambios.
El método que yo aplicaría para casos como este, es añadir un botón para guardar los cambios y como se guardaran con ese botón, si se sale sin utilizarlo, los cambios se pierden (un simple arrepentimiento de ultima hora).
Con este método:
En el evento de guardar del formulario una simple línea
IF Me.Dirty Then Me.Undo
Traducido: Si esta activo Dirty (hay cambios sin guardar) ==>> Recupera el estado original (Undo)
En el botón de guardar
RunCommand acCmdSaveRecord
Forms.[el formulario].[el combo].Requery
Forms.[el formulario].[el combo]= Me.[el dato que corresponda]
La primera línea guarda los cambios activos y pone a false Dirty
La segunda las modificaciones ya se guardaron, se actualiza el combo perfectamente
La tercera no siempre se necesita, según la importancia de los cambios puede que se pierda la referencia del elemento activo en el combo (pero no es un problema insalvable), el dato esta en el modal y aun no hemos salido ..
Se puede añadir un MSGBOX para confirmar el salvado de los cambios al salir, pero suele ser una repetitiva molestia tras la primera vez (o la segunda, depende del usuario final)
¿Cual sería el evento guardar del formulario? ¿es el botón que solemos colocar para guardar los datos? en ese caso ya tiene la macro que se genera por defecto. Y otra cosa ¿el resto de los campos del formulario que se abre en modal se guardarían si sólo hago referencia al combo? La última línea a que remite el =Me.[el dato que corresponda] ¿que objeto se espera alli?
El evento que dispara al cerrar el formulario es 'BeforeUpdate' (antes de actualizar)
Solo has de sustituir la macro por la subfunción (para que no admita mas cambios tras guardar)
Esto lo utilizo para evitar que se efectúen cambios y (sin guardarlos con el botón) se guarden al cerrar el formulario (acción por defecto).
En el botón (evento click supongo) las tres líneas para guardar los datos (todos los datos: se guarda el registro) tras ello se actualiza el combo y la tercera línea solo en el caso de que se efectúen cambios que le impidan dejar el combo en el Item seleccionado.
El dato que espera es el dato que por defecto devuelve el combo (la columna dependiente) para que tenga el Item correcto (suele ser el ID), pero depende de la programación existente.
Si en el formulario emergente se genera una copia de un registro (las variaciones serán mínimas) tendrá un ID diferente, la tercera línea sincroniza el combo con el registro en el formulario emergente.
Creo que no estoy comprendendo porque hay que guardar antes de actualizar si lo que quiero es que impacte precisamente la modificación o sea la actualización realizada en el formulario modal sobre el formulario principal o subyacente
¿este codigo de abajo iría en evento "antes de actualizar" del formulario que se abre en modal [F_vivienda_activa]?
IF Me.Dirty Then Me.Undo
¿Estas tres líneas siguientes van en el boton/comando "guardar" sustituyendo el código inscripto en el mismo comando?
RunCommand acCmdSaveRecord
Forms.[el formulario].[el combo].Requery
Forms.[el formulario].[el combo]= Me.[el dato que corresponda] (¿cuál sería acá el dato que corresponda?)
Dejemos claro que yo no he diseñado el motor de Access, solo me he preocupado en analizarlo para poder obtener el máximo rendimiento.
Cómo funcionan los eventos en Access y la secuencia que siguen los pasos de abrir, manipular y cerrar los formularios varía según se esté interactuando con ellos, quede claro que:
.- Un formulario al abrirse ‘hace una copia fiel’ del contenido de la tabla en ese momento
.- Las modificaciones en el formulario no significa que se reflejen en las tablas
.- La sincronización entre el formulario y las tablas se hacen de forma natural al guardar el registro (pero se pueden forzar).
.- Si se fuerza el guardado y tras ello se continua modificando el formulario habrá una nueva actualización: lo antes guardado y lo actual no serán lo mismo (puede ser catastrófico), lo adecuado es evitar ese conflicto y se logra con:
IF Me.Dirty Then Me.Undo
Dirty es ‘una bandera’ (True/False) que nos indica si hubo cambios en el formulario con respecto a los datos en la tabla y se necesita porque el comando UNDO (deshacer los cambios no guardados) da error si no hay cambios,.
.- Si hay cambios ‘tras el guardado forzado’: destrúyelos
.- Si no los hay: no hagas nada (no hay nada que hacer).
Lo normal cuando se toma un camino diferente, es limpiar los experimentos anteriores (tampoco el agua y el aceite se mezclan).
RunCommand es una herramienta muy versátil y poderosa y acCmdSaveRecord es la orden directa de actualizar las tablas con los datos del formulario.
Se modificó el contenido del combo, así que hay que recargarlo y por si se perdió ‘la sincronía’ entre el ITEM (elemento del combo) y el formulario, se le indica que ITEM deseamos y ‘el dato que corresponda’ es el que utilice el combo para su enlace con el formulario (su columna dependiente) que suele ser el ID.
Los combos devuelven un dato (el de su columna dependiente ¿el ID? ) Y para que muestre el ITEM que acabamos de modificar (aun continuamos en el formulario emergente) le indicamos que se desplace al ITEM que debería estar (como un dato más) en el formulario emergente, sin nombres específicos:
Forms.[el formulario].[el combo]= Me.[el dato que corresponda]
(Voy a suponer que el formulario principal se llama [Alumnos], el combo [Domicilio] y la columna dependiente de [domicilio] es el ID.)
Forms.Alumnos.Domicilio = Me.ID
Si la columna dependiente del combo devolviese la ciudad, en lugar de Me.ID ===>> Me.Ciudad
Pueden ser necesarias más actualizaciones, los cuadros de texto que muestran las columnas ocultas del combo hay que actualizarlas (lo normal es que lo hagan al dispararse el evento del combo), pero NO se disparan porque no se está interactuando (ratón/teclado) con el combo, se le está manipulando y no funcionan los modos automáticos (hay que emularlos).
Hay una alternativa (ya propuesta) que utiliza los recursos y automatismos de Access:
Abrir el formulario modal
Cerrar el formulario [Alumnos]
Actualizar lo que se quiera actualizar en el modal y cerrarlo
Tras ello volver a abrir [Alumnos] que se llenara con los datos ya actualizados.
Creo que estuve confundiendo modal con emergente. El formulario desde donde hago modificaciones y se abre con doble click desde combo domicilio esta en modo AcDialog que creo que es similar a emergente.
Private Sub vivienda_DblClick(Cancel As Integer)
DoCmd.OpenForm "F_VIVIENDA_ACTIVA", , , "id_vivienda=" & vivienda.Value, , acDialog
End Sub
Desde allí realizo y veo como los cambios en campos de texto (columnas del combo) impactan al instante en el formulario que está por detrás (el principal F_ALUMNOS) pero no así el dato modificado del domicilio que queda visible dentro del campo del combox (el campo que contiene la flechita). El id de domicilio o vivienda permanece oculto y por supuesto no es modificado. Sobre el mismo ID sólo pretendo cambiar el nombre de la calle o su nro o localidad etc y que se vea al instante una vez que cierro el formulario emergente.
Modal es modal y emergente es emergente, son propiedades que pueden activarse en conjunto o por separado.
Dialogo es la union de modal y emergente, se comporta de forma similar a un MSGBOX: mientras el este activo esperando respuesta ... la aplicación se detiene.
Lo que aprecio que no tiene claro es: como funcionan los eventos y por ello espera que lo que funciona 'normalmente' cuando interactuamos (con el ratón o el teclado) funcione sin el ratón o teclado (error conceptual).
Para que los cambios que se efectúen en un formulario 'se reflejen' en otro formulario (una copia) primero han de ser guardados en el origen (las tablas) y tras ello indicarle 'a la copia' que presente los datos actualizados (que los vuelva a obtener de las tablas), mientras esta idea no se abra camino no se entenderá como funciona Access y todo parecerá muy raro.
Hola. El formulario en modo AcDialog [F_vivienda_activa] tiene origen en una tabla "vivienda". Allí veo que impactan todas las modificaciones que realizo desde ese formulario según pude constatar. El problema es sobre el formulario principal [F_Alumnos] desde donde abro aquel otro formulario. Se visibilizan allí todos los cambios excepto el de la columna que contiene el nombre de la calle y queda visible en el combox domicilio o vivienda - combox que muestra el campo vivienda, cuadro combinado de tabla Alumnos que tiene origen de fila en una consulta sobre tabla vivienda y nomenclador de calles asociadas- ,el resto de datos o columnas del combox se muestran perfectamente en cuadros de textos.
Coloqué esta línea que me sugirió en evento antes de actualizar de F_vivienda_activa
IF Me.Dirty Then Me.Undo
y estas otras líneas en boton comando "guardar" del mismo formulario
evento al hacer click
RunCommand acCmdSaveRecord
Forms.[F_ALUMNOS].[vivienda].Requery
Forms.[F_ALUMNOS].[vivienda]= Me.[id_vivienda]
pero me da error 438 y señala en fluor sobre panel de vba problemas desde la 2da linea método Forms.[F_ALUMNOS].[vivienda].Requery
PD por lo que entendí debe llamarse a actualizar el combobox del formulario principal trayendo los cambios acontecidos en la tabla y no desde el formulario emergente? ¿por que las columnas del combox que muestro en los cuadros de texto contiguos sí se actualizan?
Debe de haber un problema con los nombres.
Me llama la atención el hecho de que se visualicen los cambios en los cuadros de texto que muestran las columnas ocultas del combo y no se actualice la columna 'visible' del combo.
¿Cómo se obtienen los datos para los cuadros de texto auxiliares?, es una pista del posible nombre real del combo que (si esta equivocado) es la causa del error.
La postdata:
Sobre porque se actualizan los cuadros de texto y no el combo (en teoría son una unidad como 'los tres mosqueteros') se podrá aclarar con tu respuesta a la pregunta que queda en el aire.
Sobre la actualización... los datos se guardan en las tablas y se manejan con los formularios,
Partimos de dos formularios abiertos en base a esos datos, [form1] y [form2] en principio son copia fiel: Tabla = Form1 = Form2
En Form2 se edita un registro (para corregir un acento), a partir de ese momento
Tabla = FORM1 y Form2 <> Tabla
Guardamos los cambios en FORM2
Tabla = Form2 y Form1 <> Tabla
Si actualizamos Form1
Tabla = Form2 = Form1
Para que los cambios en un formulario se reflejen en otro formulario se tienen que guardar los cambios (actualizar la tabla) para que el que los necesite obtenga los datos mas recientes.
Nada impide que respetando la secuencia, los cambios [en Form1] se fuercen desde [Form2] siendo conscientes de que interactuando desde [Form2] los eventos (automatismos) en [Form1] no se disparan y habrá que aplicar soluciones.
Los datos de los cuadros de texto vienen de agregar campos existentes relacionados con tabla alumnos, en este caso desde la tabla vivienda: nro de vivienda, dto, localidad, distrito. Pero en el combobox cuando se despliega la lista están visibles junto al nombre de la calle, el único que no está desplegado como visible es el id_vivienda. El combo vivienda son todas esas columnas y/o campos de tabla vivienda, la única que no actualiza desde formulario emergente es nombre de calle que queda como visible en cuadro combinado que tiene la flechita para desplegar lista. El combobox vivienda tiene origen de control "vivienda" y origen de fila en una consulta de tabla vivienda y nomenclador de calles relacionado con campo dom_calle de tabla vivienda.
En el hilo inicial consta esto:
Tengo un combo "domicilio" en un formulario principal que despliega 4 columnas con los datos completos de la vivienda -id oculto, calle, nro, dto, localidad- las cuales se muestran automaticamente en cuadros de texto contiguos una vez seleccionada la opción de la lista.
A partir de ese punto todo se complica y ‘el remate’ está aquí:
Los datos de los cuadros de texto vienen de agregar campos existentes relacionados con tabla alumnos, en este caso desde la tabla vivienda: nro de vivienda, dto, localidad, distrito.
Si los datos se toman de las columnas del combo (punto de partida) JAMAS aparecerán en la lista de ‘agregar campos existentes’.
Has estado ‘mareando la perdiz’ haciéndote derogar en una exposición clara de lo que hacías y resultados obtenidos, tienes liados los conceptos y te recomiendo de forma encarecida que los resuelvas antes de destruir el futuro de esa aplicación.
Los campos que se muestran en la lista de ‘campos existentes’ pertenecen a la tabla/consulta que constituye el origen de datos del formulario.
Los datos que conforman las columnas en los combos pertenecen exclusivamente a los combos y solo uno de ellos (la columna referente) puede utilizarse para asociar el combo (el ítem que corresponda) con el registro activo, dicho de otra forma:
En el combo TODAS las posibilidades (con una columna o con cincuenta columnas) y solo la columna referente tiene uso práctico (el resto: PAJA)
Para mostrar las ‘columnas ocultas del combo’ en cuadros de texto independientes, se tiene que hacer referencia al objeto combo y a una de sus columnas) y JAMAS DE LOS JAMASES aparecen como ‘campos existentes’.
Tienes duplicada esa parte y has de decidir qué hacer porque el actual diseño no es válido (hay duplicación de datos) y si soy sincero me parezca una solemne tontería abrir un formulario emergente para corregir algo que se puede ‘hacer a pelo’ en el formulario inicial.
(Por diseño era algo que no tenía lógica: o se toman del combo y se modifican con el combo, o se añaden al origen de datos y cambian con el registro).
Queda otra posibilidad (y seria el ‘Órdago’), que los cuadros de texto se obtuviesen mediante funciones independientes
Hola gracia por respuesta. Pero no encuentro en mi base que se estén duplicando los datos. Quizás como no soy programador no tengo el lenguaje técnico adecuado y no me hago entender bien. No sé si podría enviarte la base para que veas.
Lo que estas duplicando no son los datos, es el manejo de los datos y creo que si analizas otra vez el mensaje anterior lo veras claro.
Tienes que 'definir' la funcionalidad del formulario porque carece de sentido práctico abrir un formulario para editar los/unos datos que (directamente) se pueden manipular en el formulario original.
Por ejemplo:
.- Si se utiliza un combo es para seleccionar una de las opciones de su contenido y facilitar que una vez seleccionada se muestren datos complementarios, como el contenido de un combo no es manipulable (dejémoslo en este punto de momento), para modificar el contenido se precisa editar sus orígenes (las tablas) y utilizar un formulario para ello es correcto, que sea emergente también puede ser ideal si los datos son sensibles ...
.- Si los datos auxiliares que se deberían obtener del combo se obtienen 'sin el combo', al combo le sobran las columnas ocultas, cuando pertenecen y se obtienen del origen de datos del formulario (sea consulta o tabla), lo normal es que sean editables directamente, por lo que el formulario auxiliar para manipularlos carece de sentido.
No es mi intención publicar mi correo-e (hace ya muchos años que tome esa decisión) pero si la publicas (sea en este foro u otro en que coincidamos), me comprometo a analizar la aplicación y aportar ideas.
No tiene que ser la que tiene los datos reales, basta con que tenga el diseño y el código real, los datos (quien sea Pepe o Luis ... ni los conocerá nadie), mientras no los líes aplicando que Luís es padre de Pepe y a la vez su nieto (incoherencias) seria suficiente.
el combo vivienda esta originado por una consulta sobre tabla vivienda. Con el formulario emergente entiendo que se modifica la tabla que es la que alimenta el combo. En el formulario principal agregué cuadros de texto bloqueados en su edicion a simple efecto de mostrar el resto de las columnas del combo que no quedan visibles en el campo combo "vivienda" pero que son columnas que no están ocultas al desplegar la lista del mismo. Lo que sí noto es que hay problemas con que la clave principal sea el id_vivienda, ahi note que puede duplicarse datos por seleccionar la misma calle y mismo nro.
No le aprecio la lógica.
El combo no debería generar duplicados si su uso es el adecuado a la función, el combo puede definir zonas y con un solo dato (el ID) se puede obtener la ciudad, el barrio y el nombre de la calle, luego vendrán como datos complementarios el numero de la calle, el portal, el piso, letra ... como parte de la ficha del alumno.
Y si, podría darse el caso que en esa (una) vivienda, convivan uno o varios hermanos (la vivienda su elemento común) y aun se podrán forzar diferencias (la habitación y en ella si fuera el caso su litera).
Dejemos eso aparte y centremos al combo:
Las columnas ocultas del combo se pueden mostrar en cuadros de texto que solo se relacionen con el combo (un cambio en el combo y se actualizan automáticamente).
Es tan fácil como indicarle que 'su origen de datos' (el del cuadro de texto) es la columna xxxx del objeto combo.
- Compartir respuesta