2010-01-30 9 views
8

¿Es mejor mostrar ProgressBar UserForms en VBA como modal o no? ¿Cuáles son las mejores prácticas para desarrollar indicadores de progreso en VBA?¿Es mejor mostrar ProgressBar UserForms en VBA como modal o no?

Los UserForms sin modo requieren el uso de Application.Interactive = False, mientras que los UserForms modales por su propia naturaleza bloquean cualquier interacción con la aplicación hasta que el procedimiento principal haya finalizado o se haya cancelado.

Si se utiliza Application.Interactive = False, sin embargo, la tecla Esc interrumpe la ejecución de código, por lo que el uso de Application.EnableCancelKey = xlErrorHandler y tratamiento de errores (Err.Number = 18) es necesaria tanto en el formulario de usuario y el procedimiento de llamada.

Los procedimientos de llamadas que hacen un uso intensivo de los recursos también pueden provocar que los eventos CommandButton_Click y UserForm_Activate fallen en UserForms no moderados.

En general, los indicadores de progreso que usan UserForms modales parecen más simples, porque el código que se está ejecutando está totalmente contenido en el módulo UserForm, y hay menos necesidad de pasar variables.

El problema, sin embargo, con el uso de UserForms modales para indicadores de progreso es que se requiere un módulo UserForm por separado para cada procedimiento que necesita un indicador de progreso, porque el procedimiento de llamada debe estar dentro del procedimiento UserForm_Activate.

Por lo tanto, si bien es posible tener un único indicador de progreso reutilizable en un UserForm no modal, será menos confiable que ejecutar el código desde múltiples UserForms modales.

¿Qué camino es mejor?

Gracias!

Respuesta

1

Voy a cerrar este y decir que Modal es el ganador. Lo he intentado de ambas maneras, pero terminas tratando de cerrar demasiadas lagunas con formas de usuario no modestas. Modal es más difícil porque es más estricto, pero te alienta a dividir tu código en trozos más pequeños, lo que a la larga es mejor a largo plazo.

3

También hay una tercera forma, usando el Application.StatusBar. Incluso puede simular una barra de progreso verdadera usando una secuencia de caracteres U + 25A0 y U + 25A1.

+0

Gracias por la sugerencia de GSerg, pero he intentado usar eso en el pasado, pero Excel 2007 deja de actualizar la ventana y muestra "No responde" en la parte superior de la ventana de la aplicación. – Kuyenda

+2

No tengo mucha experiencia con Office 2007, pero ¿qué ocurre si llama a DoEvents justo después de establecer un valor en 'StatusBar'? – GSerg

+0

Eh, eso funcionó. Guau, esa es una buena opción para tener, ¿no? Gracias GSerg! – Kuyenda

1

Definitivamente Modal. Si va a considerar el modo sin formato, debe ejecutarlo en un subproceso separado fuera de proceso y no en el subproceso principal de Excel.exe.

1

Creo que el tema inicial vale la pena responder ya que la pregunta fue formulada tan bien que Google la encuentra primero.

Sección 1 - Teoría

Lo primero que decir es que para transferir las variables entre los módulos no es difícil en absoluto.

Lo único que debe hacer es crear un módulo por separado y colocar allí todas las variables globales. Entonces podrá leerlos en todas partes en todos los formularios, hojas y módulos.

Lo segundo es que la ventana debe ser MODELESS. ¿Por qué eso? La respuesta es para mantener la movilidad del código, es decir,

  1. la función donde se ejecuta el proceso más habitual no debe ser ubicado en el módulo de formulario de usuario
  2. puede llamar a la ventana con barra de progreso de todas partes y
  3. la única conexión entre la función/procedimiento de rutina son las variables globales

Esta es una gran ventaja para ser versátil aquí.

Sección 2 - Práctica

1) Crear un módulo "Declaración" con las variables globales:

StopForce Pública como número entero 'esta variable se utiliza como un indicador de que el usuario pulsa el botón de cancelación

PCTDone Pública As Single 'este es el% del trabajo que se ha hecho ya

P ublic CurrentFile As String 'cualquier otro parámetro que deseemos transferir al formulario.

2) Cree el formulario con el botón. En OnClick evento del botón debería haber un código en la que nos referimos a la variable global StopForce en Declaración módulo

Private Sub CommandButton1_Click() 

Declaration.StopForce = 1 
    End Sub 

3) Añadir un procedimiento en el que se actualiza la barra de progreso

Sub UpdateProgressBar(PCTDone_in As Single) 
With UserForm1 
    ' Update the Caption property of the Frame control. 
    .FrameProgress.Caption = Format(PCTDone_in, "0%") 
    ' Widen the Label control. 
    .LabelProgress.Width = PCTDone_in * _ 
     (.FrameProgress.Width) 
    ' Display the current file from global variable 
    .Label1.Caption = Declaration.CurrentFile 
End With 
End Sub 

4) en cualquier otro módulo debemos tener las funciones o el procedimiento/sub donde se realiza la rutina:

For i=1 to All_Files 

Declaration.CurrentFile = myFiles (i) 

FormFnc.UpdateProgressBar (i/.Range("C11").Value) 


DoEvents 

If Declaration.StopForce = 1 Then 
    GoTo 3 
End If 

Next i 
+0

Tenga en cuenta que los UserForms no moderados parecen no funcionar en absoluto en Mac OS –

Cuestiones relacionadas