** NORMAS DEL FORO **
Inicio del foro Inicio del foro > Access y VBA > Access y VBA
  Mensajes nuevos Mensajes nuevos RSS - cancelar el cierre de un formulario
  Preguntas frecuentes Preguntas frecuentes  Buscar en el foro   Eventos   Registro Registro  Iniciar sesion Iniciar sesion

Tema cerradocancelar el cierre de un formulario

 Responder Responder
Autor
Mensaje
Antonalo Ver desplegable
Asiduo
Asiduo
Avatar

Unido: 06/Noviembre/2009
Localización: España
Estado: Sin conexión
Puntos: 437
Enlace directo a este mensaje Tema: cancelar el cierre de un formulario
    Enviado: 09/Abril/2015 a las 01:03
Hola amigos

Resulta que tengo un formulario en el que quiero que cuando el campo IdEvento tome el valor 1

Entonces sea necesario dar un valor al campo IdCaso, y no deje cerrar el formulario hasta que se rellene Id caso, (O que se dé otro valor a IdEvento)

He escrito el siguiente código:

Private Sub Form_Close()
If (Me.IdEvento = 1 And Nz(Me.IdCaso, 0)) = 0 Then
   MsgBox "Falta el caso de este Evento"
   
End If

End Sub

Pero no sé que hacer para que se cancele el cierre del formulario en el caso de que la condición sea cierta.


Arriba
E. Feijoo Ver desplegable
Moderador
Moderador


Unido: 16/Abril/2004
Localización: España
Estado: Sin conexión
Puntos: 19948
Enlace directo a este mensaje Enviado: 09/Abril/2015 a las 01:26
El 'cierre' no utiliza un único evento, utiliza varios.

Solo has de utilizar uno que utilice el parámetro 'CANCEL' y aplicarlo si se dan las oportunas condiciones.

(en el foro ha salido en repetidas ocasiones, el tema: el mismo, VALIDAR el registro)

Editado por E. Feijoo - 09/Abril/2015 a las 01:27
Arriba
Antonalo Ver desplegable
Asiduo
Asiduo
Avatar

Unido: 06/Noviembre/2009
Localización: España
Estado: Sin conexión
Puntos: 437
Enlace directo a este mensaje Enviado: 09/Abril/2015 a las 10:44
E. Feijoo, gracias por la pista. Antes de hacer ninguna pregunta, siempre busco respuestas, pero no las puedo encontrar si no sé lo que tengo que buscar.

En este caso, buscaré la palabra CANCEL y me enteraré de como, cuando y para qué se usa.
Ya luego os contaré, porque no solo quiero impedir el cierre del formulario sino también impedir el cambio de registro mientras no se den las condiciones apropiadas.

Repito las condiciones: En un formulario hay un campo que se llama IdEvento y otro que se llama IdCaso. Ambos son numéricos, aunque se introducen a través de sus respectivos combos que enseñan un texto

Quiero que si, en un registro,  IdEvento toma el valor 1, no se quede el campo IdCaso vacío.


Editado por Antonalo - 09/Abril/2015 a las 10:46
Arriba
E. Feijoo Ver desplegable
Moderador
Moderador


Unido: 16/Abril/2004
Localización: España
Estado: Sin conexión
Puntos: 19948
Enlace directo a este mensaje Enviado: 09/Abril/2015 a las 14:16
Antes de 'cerrar' el formulario, Access efectua determinadas operaciones tales como guardar el registro.

Ese evento puede 'abortarse' y si se aborta se abortaría también el cierre (o el cambiarse al siguiente registro que es similar pero sin abandonar el formulario).

Asi pues, si se efectúa esa verificación de datos en el adecuado evento y de no darse las circunstancias se envía el adecuado mensaje, se aborta el guardado (lo que arrastra al aborto del cierre, pues es 'parte de lo mismo') y para mas facilidades cara al usuario se envía el foco al adecuado campo .... se lograría lo que se persigue.

En la ayuda de Access (el 'enemigo numero uno' de muchos y 'la biblia' para otros) indica el orden de eventos y la interactuación cuando se hacen 'cambios espaciales', si queda alguna duda, solo hay que 'imitar a S. Tomas' con lo de meter el dedo en la llaga: poner un mensaje en cada evento y anotar el orden en que se presenta el mensaje, si eso no ilumina hasta el ultimo rincón .... pues nada a dedicarse al Word o Excel (o a jugar al solitario).
Arriba
silver7619 Ver desplegable
Habitual
Habitual
Avatar

Unido: 13/Marzo/2006
Localización: España
Estado: Sin conexión
Puntos: 137
Enlace directo a este mensaje Enviado: 09/Abril/2015 a las 17:57
Prueba con

docmd.cancel

D.Valera
Arriba
Antonalo Ver desplegable
Asiduo
Asiduo
Avatar

Unido: 06/Noviembre/2009
Localización: España
Estado: Sin conexión
Puntos: 437
Enlace directo a este mensaje Enviado: 10/Abril/2015 a las 10:59
E. Feijoo

Gracias a tus orientaciones he resuelto el problema y he aprendido cosas.
Estoy seguro que hubieras podido darme la solución desde el principio pero
prefieres orientar y que la gente trabaje. 

He impedido que el formulario se cierre mediante el evento "al descargar"
previamente ya había encontrado Docmd.Cancel pero no sabía donde utilizarlo
porque no me funcionaba.

También uso el evento "Antes de actualizar" y con eso, la cuestión ya está resuelta.

Silver, acabo de leer tu comentario, es la palabra clave que me costo una hora encontrar.
Gracias de todos modos.

Os pego los eventos, aunque falta mejorarlos, y enviar el foco a los controles etc..
pero eso ya sé hacerlo por mi cuenta y ya lo haré.

Primero defino lo siguiente:
Private Sub ImpedirOmisiones()
Select Case IdEvento
       Case 1
             If (Nz(IdCaso, 0) = 0 Or Nz(IdPersona, 0) = 0) Then
             MsgBox "Falta introducir la persona o el caso de esta CITA NORMAL"
             DoCmd.CancelEvent
             End If
        Case 2
           If Nz(IdPersona, 0) = 0 Then
            MsgBox "Falta introducir la persona de esta CITA PERSONAL"
            DoCmd.CancelEvent
            End If
        Case 3
          If Nz(IdCaso, 0) = 0 Then
             MsgBox "Falta introducir el caso de esta GESTION"
             DoCmd.CancelEvent
        
             End If
             
       End Select
End Sub


Y ahora los eventos:

Para impedir el cambio de registro:

Private Sub Form_BeforeUpdate(Cancel As Integer)
     ImpedirOmisiones

End Sub

Y para impedir que el formulario se cierre:

Private Sub Form_Unload(Cancel As Integer)
        ImpedirOmisiones
           
End Sub

Si no tenéis ninguna sugerencia más, me doy por satisfecho y podéis cerrar.


Arriba
E. Feijoo Ver desplegable
Moderador
Moderador


Unido: 16/Abril/2004
Localización: España
Estado: Sin conexión
Puntos: 19948
Enlace directo a este mensaje Enviado: 10/Abril/2015 a las 11:47
No estas aprovechando las virtudes de Access .... (y tiene muchas, aunque también tiene sus 'caprichos').

Cuando una función tiene un parámetro, lo natural es utilizarlo (al menos en mi opinión) y CANCEL es un parámetro que 'nace' con un valor de FALSO .... ¿Qué indica esto?:

Si CANCEL = FALSO ==> no se cancela (aborta) NADA
Si CANCEL = TRUE ==> Se cancela la acción

Juguemos con lo que actualmente se aplica:
Se tiene :
Private Sub ImpedirOmisiones()

Los SUB no devuelven datos, las funciones SI (y además, una función se puede utilizar como si fuera una macro, las SUBfunciones NO)

Lo modificamos:
Private FUNCTION ImpedirOmisiones()

Y le indicamos que devuelva un valor BOOLEANO (Booleano es la definición típica de un True/False)
Private FUNCTION ImpedirOmisiones() As Boolean

Por defecto el valor devuelto es un FALSE, veamos como aplicarlo

Una de las comparaciones:
Case 2
      If Nz(IdPersona, 0) = 0 Then
        MsgBox "Falta introducir la persona de esta CITA PERSONAL"
        DoCmd.CancelEvent
        End If

¿Cancelar aquí? y si hay algo mas que hacer que la verificación ....
En lugar de cancelar 'sin mirar a otro sitio', indicamos que hay que abortar lo que sea y que sea 'el llamante' quien lo haga cuando le parezca adecuado

Asi pues le asignamos a la función el valor a devolver (un True) con lo que:
DoCmd.CancelEvent ===> ImpedirOmisiones = TRUE


Nos queda como utilizar el valor y se aplicaría asi:

Original---
Private Sub Form_Unload(Cancel As Integer)
ImpedirOmisiones
End Sub

Lo idóneo---
Private Sub Form_Unload(Cancel As Integer)
Cancel = ImpedirOmisiones
End Sub

Y si tras la asignación hay mas código, se ejecutara haciendo lo que tenga que hacer (y no se cortara de cualquier manera)

Si analizas lo expuesto, aprenderás a utilizar los parámetros de las funciones (o sub_funciones) que si el diseñador los creo será porque son el método correcto (o al menos el mas natural).
Arriba
Antonalo Ver desplegable
Asiduo
Asiduo
Avatar

Unido: 06/Noviembre/2009
Localización: España
Estado: Sin conexión
Puntos: 437
Enlace directo a este mensaje Enviado: 10/Abril/2015 a las 19:11
E. Feijoo eres un maestro en los dos sentidos de la palabra.

He entendido todo, nunca había utilizado una función aunque en los ejemplos del tutorial de Buho
ya las había visto

El código, siguiendo tus explicaciones, lo he dejado asi:

Private Function ImpedirOmisiones() As Boolean
Select Case IdEvento
       Case 1
             If (Nz(IdCaso, 0) = 0 Or Nz(IdPersona, 0) = 0) Then
                 MsgBox "Falta introducir la persona o el caso de esta CITA NORMAL"
                 ImpedirOmisiones = True
             End If
        Case 2
           If Nz(IdPersona, 0) = 0 Then
            MsgBox "Falta introducir la persona de esta CITA PERSONAL"
            ImpedirOmisiones = True
            End If

        Case 3
          If Nz(IdCaso, 0) = 0 Then
             MsgBox "Falta introducir el caso de esta GESTION"
             ImpedirOmisiones = True        
           End If
             
       End Select
End Function



Private Sub Form_BeforeUpdate(Cancel As Integer)
     Cancel = ImpedirOmisiones
End Sub


Private Sub Form_Unload(Cancel As Integer)
    Cancel = ImpedirOmisiones           
End Sub

Funciona muy bien y me gusta más que la otra . Gracias de nuevo 
Arriba
 Responder Responder
  Compartir tema   

Ir al foro Permisos de foro Ver desplegable