¿Cómo actualizar automáticamente un formulario cuando se han cambiado datos en otro formulario?

Un formulario no continuo, vamos a llamarlo principal, contiene un combo con nombres de personas. La lista de nombres no se puede modificar en ese formulario. Cuando hay que modificar o añadir un nombre de persona, mediante un comando se abre un nuevo formulario con origen en la tabla de nombres, en el que se pueden corregir y añadir nombres.

Al terminar de editar o añadir nombres cierro la ventana y vuelvo al formulario principal.

Naturalmente, el formulario principal no se da por enterado de que la tabla nombres ha cambiado y tengo que actualizarlo, lo que hago ejecutando una macro que actualiza el formulario principal y sus subformularios.

Lo que hace la macro (traducida a VBA, porque no sé cómo pegar aquí las instrucciones de la macro) es esto:
        TempVars. Add "Busca", .IDVolumen 'Almacena en una variable el registro actual
        DoCmd.GoToControl "[SFVolumenAutor]" 'Va al primer subformulario del principal
        DoCmd.Requery "" 'Lo actualiza
        DoCmd.GoToControl "[SFVolumenDibujante]" 'Va al segundo subformulario del principal
        DoCmd.Requery "" ' Lo actualiza
        DoCmd.GoToControl "[SFVolumenEditorial]" 'Va al tercer subformulario del principal
        DoCmd.Requery "" 'Lo actualiza
        DoCmd.GoToControl "[SFVolumenObra]" 'Va al cuarto subformulario del principal
        DoCmd.Requery "" 'Lo actualiza
        DoCmd.GoToControl "[IDVolumen]" 'Va al formulario principal
        DoCmd.Requery ""' 'Lo actualiza
        DoCmd.SearchForRecord acForm, "Volumen", acFirst, "[IDVolumen]=" & TempVars!Busca 'Vuelve al registro inicial
        TempVars. Remove "Busca" 'Elimina la variable temporal

Me gustaría automatizar el proceso, de modo que al cerrar el formulario de nombres el formulario principal y sus subformularios se actualizasen automáticamente, pero no logro descubrir dónde debo incluir las instrucciónes de actualización. Si al cerrar o descargar el formulario de nombres o al volver al formulario principal. En este último caso, sin que sea necesario cerrar y volver a abrir el formulario principal y sin que las instrucciones de actualización se ejecuten cada vez que navego por los registros del formulario principal, porque me parece una pérdida de tiempo actualizar cuando no hace falta.

1 respuesta

Respuesta
3

Puedes hacerlo de muchas formas. Por ejemplo, para que el combo( al que llamaremos Elegir) te recoja ese nuevo nombre, basta con que en sus propiedades-eventos-al recibir el enfoque crees un procedimiento de evento y entre Private Sub y End sub pongas

Elegir. Requery

Eso lo que hace es que "obliga" a que el combinado reconsulte su origen de la fila. Y si los subformularios, están relacionados con el formulario por un campo común, sin que le digas nada ya "reconsultan" ellos.

Vamos a suponer que en un combinado del formulario Facturas, eliges nombres de clientes, y en sus propiedades-Datos-limitar a la lista le tienes puesto que sí. Vamos a suponer que escribes un nombre que no está. Al pulsar Enter, que te avise y se abra el formulario Clientes para darlo de "alta" y que luego ya te aparezca en el combinado. Podrías usar

Private Sub Idcliente_NotInList(NewData As String, Response As Integer)
End Sub

De forma, que en el momento que terminaras de escribir sus datos y cerraras el formulario Clientes, en el combinado del formulario Ventas ya te aparecería ese nombre

Gracias! 

El primer sistema que me propones lo entiendo perfectamente, pero el segundo me plantea una duda.

SI contesto sí, que quiero añadir el nombre a la lista, lo que ocurre en tu sistema es que se abre el formulario de nombres, que es lo que yo hago ahora, aunque sin la pregunta de si quiero añadir o no el nombre a la lista.

Es decir, cuando el nombre no está en el combo, pulso un comando y se abre el formulario de nombres. Al terminar, no se ha actualizado el formulario principal.

Sin embargo, con el segundo sistema que me propones sí se actualiza el combo, y no entiendo a qué se debe la diferencia. Ten en cuenta que trabajo fundamentalmente con macros y hay muchas cosas de VBA que se me escapan, pero querría saber por qué se actualiza el combo si abro el formulario con tu sistema y no lo hace cuando abro el formulario con el mío (Otra vez es una traducción a VBA de una macro):

        If (Eval("[IDÍndice] Is Not Null")) Then

            TempVars.Add "Busca", .IDÍndice 'Esto es para ir al registro concreto si pulso el comando cuando hay un nombre en el combo
        End If
        DoCmd.OpenForm "FS_Nombres", acNormal, "", "", , acNormal
        If (Eval("[TempVars]![Busca] Is Not Null")) Then
            DoCmd.SearchForRecord acForm, "FS_Nombres", acFirst, "[IDNombres ]=" & TempVars!Busca
            TempVars.Remove "Busca"
           End If

Si tengo un formulario basado en la tabla Ventas, donde en vez de nombre del cliente tengo el Idcliente

Si ahora escribo un nombre, que te garantizó que no está en la tabla Clientes

Cuando escribo el nombre y pulso Enter

Si le digo que Sí, primero me "borra" lo escrito en el combinado y

Cuando cierro el formulario Clientes

Ya me aparece en el combinado, y el código es exactamente el que te puse en el evento Al no estar en lista.

Gracias de nuevo Julián:

A pesar de mis limitaciones con el VBA había entendido (casi entero) el código que me mandaste inicialmente.

Voy a usar, de hecho ya lo he implementado, el primer sistema que me comentaste, porque es más sencillo y funciona perfectamente. Solo le he añadido la instrucción posterior SetFocus, para evitar que la primera vez que entro en el combo actualizado la lista desplegable aparezca y desaparezca inmediatamente, quedando así:

Private Sub IDÍndice_GotFocus()
    Me.IDÍndice.Requery
    Me.IDÍndice.SetFocus
 End Sub

La duda, ya más curiosidad que otra cosa, era saber qué hay en mi código de apertura del formulario de nombres que impide la actualización del combo. ¿Es porque lo abro en modo normal y tú lo haces en modo de adición? ¿O es porque tu código se ejecuta desde el propio combo y el mío desde un comando situado fuera del combo? Ya no se me ocurren más razones para la diferencia, y ya que te tomas la molestia de resolver mis dudas, me molesta no ser capaz de entender totalmente tus soluciones.

En todo caso, gracias como siempe

No lo sé, tendría que ver el diseño del formulario.

Por cierto, no hace falta ir subformulario por subformulario para que "reconsulte". Puedes usar, por ejemplo

for each control in form.controls

if control.controltype=acsubform then

control.requery

end if

next

Con lo cual te va "recorriendo" los subformularios, y es mucho más corto

¡Gracias! 

Me ha gustado la iteración para recorrer los controles del formulario. LAmentablemente las macros no las aceptan

Saludos

Una macro no deja de ser un trozo de código vb para hacer operaciones simples, al que le han puesto un nombre en "cristiano".

Lo mismo que la macro la asignas a un evento de un objeto, se puede hacer lo mismo, pero en vez de poner el nombre de la macro, pulsas el botón de los tres puntos de la derecha y se abrirá una ventana, donde si seleccionas generador de código se abre el edito de Vb y ahí es donde puedes poner lo de for...

Por ejemplo, si la macro no es de las incrustadas, que por lo que pones creo que no es, en vista diseño del formulario pulsa el botón que te marco y verás como te convierte la macro en VB, y eso es lo verdadero que le dices.

Otro ejemplo, supongamos que haces una macro con Ir a registro siguiente. En realidad le estás diciendo, aunque no lo veas, en código VB

Docmd. Gotorecord,, acnext

¡Gracias! 

Ya he incluido líneas de código en mi base, porque uso instrucciones de más de 255 caracteres que no son válidas en una macro.

Pero eso no quita que no esté familiarizado con el VBA y que me lleve bastante tiempo hacer la traducción, porque la traducción automática de Access no siempre funciona bien. Sobre todo al operar con variables.

En el caso de la iteración que me sugeriste, tendría que traducir una macro que, en realidad, no quiero usar. Porque mi pregunta inicial era cómo conseguir que los combos del formulario se actualicen automáticamente al añadir contenido a las listas que los alimentan, evitándome tener que activar manualmente un comando que actualice el formulario principal y sus subformularios.

Si al final tuviese que usar el comando para actualizar, sí traduciría la macro y usaría la iteración que me propusiste, porque es mucho más elegante hacerlo así que como lo hace mi macro: yendo de subformulario en subformulario y actualizándolos individualmente. Aparte de que, para mí, una buena instrucción es la que sirve aunque cambies cosas en el formulario. Y eso es lo que pasa con la tuya. Que si añado o quito subformularios los actualizará todos, mientras que mi macro solo sirve para los formularios que tengo ahora. Si quito alguno, la macro dará error, porque le estaré diciendo que vaya a un subformulario que no existe. Y si añado alguno, no lo actualizará.

Saludos

Si tengo el formulario con dos combinados llamados ElegirCliente y ElegirPais. Como no sé como "das de alta" los futuros valores de los combinados para el ejemplo he puesto un botón que me abrirá el formulario Clientes. Puedes ver que tu nombre no está

Como tampoco está Indonesia

Ahora pulso el botón y escribo lo que sea

Cuando cierro este formulario y despliego el combinado ElegirCliente, ya estás

Y cuando despliego el combinado ElegirPais, ya está Indonesia

En este caso particular, ya que no sé cuando haces "las altas", en el evento Al cerrar del formulario Clientes te tengo puesto

Private Sub Form_Close()
If CurrentProject.AllForms("formulario1").IsLoaded Then
Forms!formulario1!ElegirCliente.Requery
Forms!formulario1!ElegirPais.Requery
End If
End Sub

Es decir, si el formulario Formulario1 está cargado, que si lo está, ya que el de Clientes lo hemos abierto desde él, que ambos combinado "reconsulten" su origen de la fila.

Pero como te digo, es para este caso en particular, ya que se pueden hacer de mil formas. Por otro lado, te garantizo, con una certeza del 100%, que si sigues en esto del Access dejarás las macros y te pasarás a VB. Ten en cuenta que todo el entorno Windows está hecho en su 90% en lenguaje VB en sus diferentes versiones, y las macros, como te dije, fueron creadas para operaciones sencillas.

¡Gracias! 

Disculpa la tardanza en contestarte, pero ha sido una semana muy liada.

Acabo de implementar el código que me has mandado y funciona perfectamente, así que gracias de nuevo.

Saludos

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas