2010-10-20 142 views
13

Supongamos que tengo un botón incrustado en mi hoja de cálculo que inicia alguna función de VBA.¿Cómo detener la ejecución del código VBA?

Private Sub CommandButton1_Click() 
    SomeVBASub 
End Sub 

Private Sub SomeVBASub 
    DoStuff 
    DoAnotherStuff 
    AndFinallyDothis 
End Sub 

me gustaría tener la oportunidad de tener algún tipo de un botón "cancelar" que pararía SomeVBASub ejecución en un momento arbitrario, y no estoy en la participación de Ctrl+Break aquí, porque yo había me gusta hacerlo silenciosamente

Supongo que este debería ser un problema bastante común, ¿alguna idea?

Gracias.

Respuesta

18

Agregue otro botón llamado "CancelButton" que establece un indicador, y luego verifique ese indicador.

Si tiene bucles largos en el "material", verifique que estén allí también y salga si está configurado. Use DoEvents dentro de bucles largos para asegurarse de que la IU funcione.

Bool Cancel 
Private Sub CancelButton_OnClick() 
    Cancel=True 
End Sub 
... 
Private Sub SomeVBASub 
    Cancel=False 
    DoStuff 
    If Cancel Then Exit Sub 
    DoAnotherStuff 
    If Cancel Then Exit Sub 
    AndFinallyDothis 
End Sub 
+2

tuve una idea para implementar este tipo de lógica, pero bastante me embarasses poner 'DoEvents-Check flag' chain en CADA posible punto de salida del procedimiento (literalmente, después de casi cada cadena). –

+2

El método @Fahemita que se describe a continuación lo evita, pero funciona prácticamente igual que Ctrl + Break. Depende de cuánto control desee sobre la interfaz de usuario (p.un botón) y donde puede permitir que su código salga. Si la IU no es importante y el código sale puede ser arbitrario (por ejemplo, no hay problemas con dependencias, retrocesos, etc.), entonces sería más fácil. Por lo general, agregar trampas para un indicador de cancelación no es demasiado engorroso, ya que la mayor parte del tiempo de ejecución se usaría en bucles, pero tal vez ese no sea el caso en su situación. –

+2

Permítanme también agregar que si le preocupa que el procedimiento no se detenga inmediatamente cuando hacen clic en "cancelar" (de ahí la necesidad de que agregue tantas comprobaciones), lo que hago normalmente es deshabilitar el botón Cancelar y cambiar el texto a "Espere ..." o algo en el procedimiento Click, para que el usuario sepa que la aplicación realmente está considerando su solicitud. –

0

lo jamietre dijo, pero

Private Sub SomeVBASub 
    Cancel=False 
    DoStuff 
    If not Cancel Then DoAnotherStuff 
    If not Cancel Then AndFinallyDothis 
End Sub 
9

¿Qué tal Application.EnableCancelKey - Utilice el botón Esc

On Error GoTo handleCancel 
Application.EnableCancelKey = xlErrorHandler 
MsgBox "This may take a long time: press ESC to cancel" 
For x = 1 To 1000000 ' Do something 1,000,000 times (long!) 
    ' do something here 
Next x 

handleCancel: 
If Err = 18 Then 
    MsgBox "You cancelled" 
End If 

de fragmentos de http://msdn.microsoft.com/en-us/library/aa214566(office.11).aspx

2

O, si se quiere evitar el uso de un variable global podría utilizar el .Tag propiedad rara vez se utiliza el formulario de usuario de:

Private Sub CommandButton1_Click() 
    Me.CommandButton1.Enabled = False 'Disabling button so user cannot push it 
             'multiple times 
    Me.CommandButton1.caption = "Wait..." 'Jamie's suggestion 
    Me.Tag = "Cancel" 
End Sub 

Private Sub SomeVBASub 
    If LCase(UserForm1.Tag) = "cancel" Then 
     GoTo StopProcess 
    Else 
     'DoStuff 
    End If 

Exit Sub 
StopProcess: 
    'Here you can do some steps to be able to cancel process adequately 
    'i.e. setting collections to "Nothing" deleting some files... 
End Sub 
0

que hacer esto mucho. Mucho. :-)

Me he acostumbrado a usar "DoEvents" con más frecuencia, pero todavía tiendo a configurar las cosas sin realmente verificar dos veces un método de parada segura.

Luego, hoy, habiéndolo hecho nuevamente, pensé: "Bueno, solo espero el final en 3 horas", y comencé a remar en la cinta. Anteriormente, había notado en la sección "Ver" de la cinta un desplegable de "Macros", y pensé en echar un vistazo para ver si podía ver mi macro interminable ...

Ahora me doy cuenta de que puedes también obtén esto usando Alt-F8.

Entonces pensé, ¿qué pasaría si "entrara" en una Macro diferente, me rescataría? Lo hizo :-) También funciona si te pones en la macro en ejecución (pero aún así pierdes donde estás), a menos que seas un programador muy perezoso como yo y declare muchas variables "globales", en cuyo caso el los datos globales se mantiene :-)

K

0

~ para aquellos que utilizan la caja de entrada personalizado

Private Sub CommandButton1_Click() 

DoCmd.Close acForm, Me.Name 
End 

End Sub 
Cuestiones relacionadas